private static unsafe bool CookTxPicImpl(RName rn, string targetPath, bool copyRInfo, bool isandroid) { var xnd = EngineNS.IO.XndHolder.SyncLoadXND(rn.Address); if (xnd == null) { return(false); } var targetXnd = EngineNS.IO.XndHolder.NewXNDHolder(); var txDesc = new EngineNS.CTxPicDesc(); { var attr = xnd.Node.FindAttrib("Desc"); if (attr.Version != 3) { return(false); } attr.BeginRead(); attr.Read((IntPtr)(&txDesc), sizeof(EngineNS.CTxPicDesc)); attr.EndRead(); var sattr = targetXnd.Node.AddAttrib("Desc"); sattr.Version = 3; sattr.BeginWrite(); sattr.Write((IntPtr)(&txDesc), sizeof(EngineNS.CTxPicDesc)); sattr.EndWrite(); } byte[] pngData = null; if (copyRInfo) { var attr = xnd.Node.FindAttrib("PNG"); if (attr == null) { return(false); } attr.BeginRead(); attr.Read(out pngData, (int)attr.Length); attr.EndRead(); if (copyRInfo) { var sattr = xnd.Node.AddAttrib("PNG"); sattr.BeginWrite(); sattr.Write(pngData, pngData.Length); sattr.EndWrite(); } } bool hasCompressData = false; if ((TexCompressFlags & ETexCompressMode.ETC2) != 0 && txDesc.EtcFormat != ETCFormat.UNKNOWN) { hasCompressData = true; using (var etcBlob = EngineNS.Support.CBlobProxy2.CreateBlobProxy()) { fixed(byte *dataPtr = &pngData[0]) { var texCompressor = new EngineNS.Bricks.TexCompressor.CTexCompressor(); texCompressor.EncodePng2ETC((IntPtr)dataPtr, (uint)pngData.Length, txDesc.EtcFormat, txDesc.MipLevel, etcBlob); etcBlob.BeginRead(); } if (etcBlob.DataLength >= 0) { var etcNode = targetXnd.Node.AddNode("EtcMips", 0, 0); int fmt = 0; int MipLevel = 0; etcBlob.Read(out fmt); etcBlob.Read(out MipLevel); var layer = new EngineNS.Bricks.TexCompressor.ETCLayer(); for (int i = 0; i < MipLevel; i++) { etcBlob.Read(out layer); byte[] etcMipData; etcBlob.Read(out etcMipData, (int)layer.Size); var mipAttr = etcNode.AddAttrib($"Mip_{i}"); mipAttr.BeginWrite(); mipAttr.Write(layer); mipAttr.Write(etcMipData, etcMipData.Length); mipAttr.EndWrite(); } } } } if ((TexCompressFlags & ETexCompressMode.ASTC) != 0) { //"AstcMips" hasCompressData = true; //EngineNS.Editor.Runner.ProcessExecuter.RunProcess("astcenc -cl example.png example.astc 6x6 -medium",.....) } if ((TexCompressFlags & ETexCompressMode.PNG) != 0 || hasCompressData == false) { var mipsNode = xnd.Node.FindNode("PngMips"); if (mipsNode == null) { return(false); } var smipsNode = targetXnd.Node.AddNode("PngMips", 0, 0); int curMip = 0; while (curMip < txDesc.MipLevel) { var mipAttr = mipsNode.FindAttrib($"Mip_{curMip}"); var smipAttr = smipsNode.AddAttrib($"Mip_{curMip}"); curMip++; mipAttr.BeginRead(); byte[] pngMipData; mipAttr.Read(out pngMipData, (int)mipAttr.Length); mipAttr.EndRead(); smipAttr.BeginWrite(); smipAttr.Write(pngMipData, pngMipData.Length); smipAttr.EndWrite(); } } EngineNS.IO.XndHolder.SaveXND(targetPath, targetXnd); CMDEngine.CMDEngineInstance.AddAssetInfos(targetPath); return(true); }
public static void SaveTxPic(IO.XndHolder xnd, ref CTxPicDesc txDesc, Bitmap tagBitmap, ETCFormat etcFormat = ETCFormat.RGBA8, int mipMapLevel = 0) { #region Png var attr = xnd.Node.AddAttrib("PNG"); attr.BeginWrite(); var tagStream = new MemoryStream(); tagBitmap.Save(tagStream, System.Drawing.Imaging.ImageFormat.Png); var pngData = tagStream.ToArray(); attr.Write(pngData, pngData.Length); attr.EndWrite(); #endregion #region PngMips var mipsNode = xnd.Node.AddNode("PngMips", 0, 0); int curMip = 0; while (true) { var mipAttr = mipsNode.AddAttrib($"Mip_{curMip}"); curMip++; mipAttr.BeginWrite(); var mipStream = new MemoryStream(); tagBitmap.Save(mipStream, System.Drawing.Imaging.ImageFormat.Png); var pngMipData = mipStream.ToArray(); mipAttr.Write(pngMipData, pngMipData.Length); mipAttr.EndWrite(); if (txDesc.MipLevel == curMip) { break; } if (tagBitmap.Width == 1 && tagBitmap.Height == 1) { break; } var mipWidth = tagBitmap.Width / 2; var mipHeight = tagBitmap.Height / 2; if (mipWidth == 0) { mipWidth = 1; } if (mipHeight == 0) { mipHeight = 1; } //tagBitmap = EngineNS.BitmapProc.ScaleBitmap(tagBitmap, mipWidth, mipHeight); tagBitmap = EngineNS.BitmapProc.GenerateMip(tagBitmap, mipWidth, mipHeight); } #endregion if (CEngine.IsWriteEtc) { if (etcFormat != ETCFormat.UNKNOWN) { using (var etcBlob = EngineNS.Support.CBlobProxy2.CreateBlobProxy()) { unsafe { fixed(byte *dataPtr = &pngData[0]) { var texCompressor = new EngineNS.Bricks.TexCompressor.CTexCompressor(); texCompressor.EncodePng2ETC((IntPtr)dataPtr, (uint)pngData.Length, etcFormat, mipMapLevel, etcBlob); etcBlob.BeginRead(); } } if (etcBlob.DataLength >= 0) { var etcNode = xnd.Node.AddNode("EtcMips", 0, 0); int fmt = 0; int MipLevel = 0; etcBlob.Read(out fmt); etcBlob.Read(out MipLevel); var layer = new EngineNS.Bricks.TexCompressor.ETCLayer(); for (int i = 0; i < MipLevel; i++) { etcBlob.Read(out layer); byte[] etcMipData; etcBlob.Read(out etcMipData, (int)layer.Size); var mipAttr = etcNode.AddAttrib($"Mip_{i}"); mipAttr.BeginWrite(); mipAttr.Write(layer); mipAttr.Write(etcMipData, etcMipData.Length); mipAttr.EndWrite(); } } } } } attr = xnd.Node.AddAttrib("Desc"); txDesc.MipLevel = curMip; txDesc.EtcFormat = etcFormat; #region Desc attr.Version = 3; attr.BeginWrite(); unsafe { fixed(EngineNS.CTxPicDesc *descPin = &txDesc) { attr.Write((IntPtr)(descPin), sizeof(EngineNS.CTxPicDesc)); } } attr.EndWrite(); #endregion }