public override void Export(Asset asset, string path) { var texture = (asset as Texture); var tdx = (texture.SupportingDocuments["Source"] as TDX); var sw = new System.Diagnostics.Stopwatch(); sw.Start(); if (tdx == null) { tdx = new TDX(); var b = (texture.SupportingDocuments["Source"] as Bitmap); SceneManager.Current.UpdateProgress(string.Format("Saving {0}", texture.Name)); var flags = Squish.SquishFlags.kDxt1; tdx.Name = texture.Name; tdx.Format = settings.GetSetting<D3DFormat>("Format"); switch (tdx.Format) { case D3DFormat.DXT1: flags = Squish.SquishFlags.kDxt1; break; case D3DFormat.DXT5: flags = Squish.SquishFlags.kDxt5; break; } var mip = new ToxicRagers.Generics.MipMap(); mip.Width = b.Width; mip.Height = b.Height; byte[] data = new byte[b.Width * b.Height * 4]; byte[] dest = new byte[Squish.Squish.GetStorageRequirements(b.Width, b.Height, flags | Squish.SquishFlags.kColourIterativeClusterFit | Squish.SquishFlags.kWeightColourByAlpha)]; var bmpdata = b.LockBits(new Rectangle(0, 0, mip.Width, mip.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); Marshal.Copy(bmpdata.Scan0, data, 0, data.Length); b.UnlockBits(bmpdata); SceneManager.Current.UpdateProgress(string.Format("Compressing {0} (this may take a moment)", texture.Name)); Squish.Squish.CompressImage(data, b.Width, b.Height, ref dest, flags | Squish.SquishFlags.kColourClusterFit); mip.Data = dest; tdx.MipMaps.Add(mip); } tdx.Save(Path.GetDirectoryName(path) + "\\" + texture.Name + ".tdx"); sw.Stop(); Console.WriteLine(sw.Elapsed); SceneManager.Current.UpdateProgress(string.Format("{0}.tdx saved!", texture.Name)); }
public void GetTextureFromZAD() { if (File.Exists(ZADFile)) { ZAD currentZAD = ZAD.Load(ZADFile); var zadEntry = (from entry in currentZAD.Contents where entry.Name == ZADEntryLocation || entry.Name == ZADEntryLocation.Replace("\\", "/") select entry).First(); var buffer = currentZAD.ExtractToBuffer(zadEntry); if (buffer != null) using (MemoryStream stream = new MemoryStream(buffer)) { texture = TDX.Load(stream, zadEntry.Name); } } }
public static byte[] Save(TDX tdx) { byte[] buffer; using (MemoryStream ms = new MemoryStream()) using (BinaryWriter bw = new BinaryWriter(ms)) { bw.Write(new byte[] { 0, 2 }); bw.Write((short)tdx.MipMaps[0].Width); bw.Write((short)tdx.MipMaps[0].Height); bw.Write((short)tdx.MipMaps.Count); bw.Write((int)tdx.flags); bw.WriteString(tdx.ShortFormat); for (int i = 0; i < tdx.MipMaps.Count; i++) { bw.Write(tdx.MipMaps[i].Data); } bw.Flush(); ms.Flush(); buffer = ms.ToArray(); } return buffer; }
public static TDX LoadFromBitmap(Bitmap asset, string name, D3DFormat format) { TDX tdx = null; if (tdx == null) { tdx = new TDX(); var b = asset; var flags = Squish.SquishFlags.kDxt1; tdx.Name = name; tdx.Format = format; switch (tdx.Format) { case D3DFormat.DXT1: flags = Squish.SquishFlags.kDxt1; break; case D3DFormat.DXT5: flags = Squish.SquishFlags.kDxt5; break; } var mipBitmaps = GenerateMips(b, b.Width, b.Height); foreach (var mb in mipBitmaps) { var mip = new MipMap(); mip.Width = mb.Width; mip.Height = mb.Height; byte[] data = new byte[mb.Width * mb.Height * 4]; byte[] dest = new byte[Squish.Squish.GetStorageRequirements(mb.Width, mb.Height, flags | Squish.SquishFlags.kColourIterativeClusterFit | Squish.SquishFlags.kWeightColourByAlpha)]; int ii = 0; for (int y = 0; y < mb.Height; y++) { for (int x = 0; x < mb.Width; x++) { var p = mb.GetPixel(x, y); data[ii + 0] = p.R; data[ii + 1] = p.G; data[ii + 2] = p.B; data[ii + 3] = p.A; ii += 4; } } if (format == D3DFormat.ATI2) dest = BC5Unorm.Compress(data, (ushort)mb.Width, (ushort)mb.Height, GetMipSize(format, (ushort)mb.Width, (ushort)mb.Height)); else Squish.Squish.CompressImage(data, mb.Width, mb.Height, ref dest, flags | Squish.SquishFlags.kColourClusterFit); mip.Data = dest; tdx.MipMaps.Add(mip); } } return tdx; }
public static TDX Load(Stream stream, string name = null) { TDX tdx = new TDX { Name = name }; using (BinaryReader br = new BinaryReader(stream)) { if (br.ReadByte() != 0x00 || br.ReadByte() != 0x02) { Logger.LogToFile(Logger.LogLevel.Error, "This isn't a valid TDX"); return null; } tdx.width = br.ReadUInt16(); tdx.height = br.ReadUInt16(); int mipCount = br.ReadUInt16(); tdx.flags = (Flags)br.ReadUInt32(); tdx.Format = (D3DFormat)br.ReadUInt32(); if (tdx.flags.HasFlag(Flags.ExtraData)) { int extraDataLength = (int)br.ReadUInt32(); int extraDataType = br.ReadUInt16(); switch (extraDataType) { case 0: tdx.extraDataType = ExtraDataTypes.Font; tdx.extraData = new FontDefinition(br.ReadBytes(extraDataLength - 2)); break; case 1: tdx.extraDataType = ExtraDataTypes.Animation; tdx.extraData = new AnimationDefinition(br.ReadBytes(extraDataLength - 2)); break; case 3: tdx.extraDataType = ExtraDataTypes.VTMap; tdx.extraData = new VTMap(br.ReadBytes(extraDataLength - 2)); break; default: throw new NotImplementedException(string.Format("Unknown Extra Data flag: {0}", extraDataType)); } } for (int i = 0; i < mipCount; i++) { var mip = new MipMap(); mip.Width = tdx.width >> i; mip.Height = tdx.height >> i; switch (tdx.Format) { case D3DFormat.A8R8G8B8: mip.Data = br.ReadBytes(mip.Width * mip.Height * 4); break; case D3DFormat.A8: mip.Data = br.ReadBytes(mip.Width * mip.Height); break; case D3DFormat.DXT1: mip.Data = br.ReadBytes((((mip.Width + 3) / 4) * ((mip.Height + 3) / 4)) * 8); break; case D3DFormat.ATI2: case D3DFormat.DXT5: mip.Data = br.ReadBytes((((mip.Width + 3) / 4) * ((mip.Height + 3) / 4)) * 16); break; default: Logger.LogToFile(Logger.LogLevel.Error, "Unknown format: {0}", tdx.Format); return null; } tdx.MipMaps.Add(mip); } } return tdx; }
public static TDX Load(string path) { Logger.LogToFile(Logger.LogLevel.Info, "{0}", path); TDX tdx = new TDX(); using (MemoryStream ms = new MemoryStream(File.ReadAllBytes(path))) { tdx = Load(ms, Path.GetFileNameWithoutExtension(path)); } return tdx; }