public static void RunPVRTexTool(Bitmap bitmap, AssetBundle bundle, string path, AssetAttributes attributes, bool mipMaps, bool highQualityCompression, PVRFormat pvrFormat, byte[] CookingRulesSHA1) { int width = bitmap.Width; int height = bitmap.Height; bool hasAlpha = bitmap.HasAlpha; int potWidth = TextureConverterUtils.GetNearestPowerOf2(width, 8, 2048); int potHeight = TextureConverterUtils.GetNearestPowerOf2(height, 8, 2048); var args = new StringBuilder(); switch (pvrFormat) { case PVRFormat.PVRTC4: if (!hasAlpha) { args.Append(" -f PVRTC1_2"); } else { args.Append(" -f PVRTC1_4"); } width = height = Math.Max(potWidth, potHeight); break; case PVRFormat.PVRTC4_Forced: args.Append(" -f PVRTC1_4"); width = height = Math.Max(potWidth, potHeight); break; case PVRFormat.PVRTC2: args.Append(" -f PVRTC1_2"); width = height = Math.Max(potWidth, potHeight); break; case PVRFormat.ETC2: args.Append(" -f ETC1 -q etcfast"); break; case PVRFormat.RGB565: if (hasAlpha) { Console.WriteLine("WARNING: texture has alpha channel. " + "Used 'RGBA4444' format instead of 'RGB565'."); args.Append(" -f r4g4b4a4 -dither"); } else { args.Append(" -f r5g6b5"); } break; case PVRFormat.RGBA4: args.Append(" -f r4g4b4a4 -dither"); break; case PVRFormat.ARGB8: args.Append(" -f r8g8b8a8"); break; } if (highQualityCompression && (new [] { PVRFormat.PVRTC2, PVRFormat.PVRTC4, PVRFormat.PVRTC4_Forced }.Contains (pvrFormat))) { args.Append(" -q pvrtcbest"); } var pvrPath = Toolbox.GetTempFilePathWithExtension(".pvr"); var tgaPath = Path.ChangeExtension(pvrPath, ".tga"); try { if (hasAlpha) { bitmap = TextureConverterUtils.BleedAlpha(bitmap); } TextureConverterUtils.SaveToTGA(bitmap, tgaPath, swapRedAndBlue: true); if (mipMaps) { args.Append(" -m"); } args.AppendFormat(" -i \"{0}\" -o \"{1}\" -r {2},{3} -shh", tgaPath, pvrPath, width, height); #if MAC var pvrTexTool = GetToolPath("PVRTexTool"); #else var pvrTexTool = GetToolPath("PVRTexToolCli"); #endif if (Process.Start(pvrTexTool, args.ToString()) != 0) { throw new Lime.Exception($"PVRTextTool error\nCommand line: {pvrTexTool} {args}\""); } bundle.ImportFile(pvrPath, path, 0, "", attributes, CookingRulesSHA1); } finally { DeletePossibleLockedFile(tgaPath); DeletePossibleLockedFile(pvrPath); } }
public override void Read(BinaryReader br) { long offset = br.BaseStream.Position; br.BaseStream.Seek(4, SeekOrigin.Current); //"GBIX" GBIXSize = br.ReadUInt32(); GBIXContent = br.ReadBytes((int)GBIXSize); br.BaseStream.Seek(4, SeekOrigin.Current); //"PVRT" Size = br.ReadUInt32(); Type = (PVRType)br.ReadByte(); Format = (PVRFormat)br.ReadByte(); br.BaseStream.Seek(2, SeekOrigin.Current); Width = br.ReadUInt16(); Height = br.ReadUInt16(); if (Format == PVRFormat.VQ) { var palette = new Color4[1024]; for (int i = 0; i < palette.Length; i++) { palette[i] = ReadColor(br); } var bytes = new byte[Width * Height / 4]; for (int i = 0; i < Width * Height / 4; i++) { bytes[i] = br.ReadByte(); } DecodeVQ(bytes, palette); } else if (Type == PVRType.RGB565 || Type == PVRType.ARGB1555 || Type == PVRType.ARGB4444) { Pixels = new Color4[Width * Height]; for (int i = 0; i < Width * Height; i++) { Pixels[i] = ReadColor(br); } Unswizzle(); } else if (Type == PVRType.DDS_RGB24 || Type == PVRType.DDS_RGBA32) { Dds image = Dds.Create(br.BaseStream, new PfimConfig()); byte[] pixels = image.Data; Pixels = new Color4[image.Width * image.Height]; for (int i = 0; i < image.Width * image.Height; i++) { int index = i * image.BytesPerPixel; if (image.BytesPerPixel > 3) { if (pixels[index + 3] < 0.8) { HasTransparency = true; } Pixels[i] = new Color4(pixels[index + 2], pixels[index + 1], pixels[index], pixels[index + 3]); } else { HasTransparency = false; Pixels[i] = new Color4(pixels[index + 2], pixels[index + 1], pixels[index], 255); } } } else { throw new NotImplementedException(); } }