/*--------------------------------------- * * Code ported from AboodXD's GTX Extractor https://github.com/aboood40091/GTX-Extractor/blob/master/gtx_extract.py * * With help by Aelan! * *---------------------------------------*/ /*var s_textureFormats[] = { * // internalFormat, gxFormat, glFormat, fourCC, nutFormat, name, bpp, compressed * { FORMAT_RGBA_8888, GX2_SURFACE_FORMAT_TCS_R8_G8_B8_A8_UNORM, GL_RGBA8, 0x00000000, 0x11, "RGBA_8888", 0x20, 0 }, * { FORMAT_ABGR_8888, GX2_SURFACE_FORMAT_TCS_R8_G8_B8_A8_UNORM, GL_RGBA8, 0x00000000, 0x0E, "ABGR_8888 (WIP)", 0x20, 0 }, * { FORMAT_DXT1, GX2_SURFACE_FORMAT_T_BC1_UNORM, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 0x31545844, 0x00, "DXT1", 0x40, 1 }, * { FORMAT_DXT3, GX2_SURFACE_FORMAT_T_BC2_UNORM, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, 0x33545844, 0x01, "DXT3", 0x80, 1 }, * { FORMAT_DXT5, GX2_SURFACE_FORMAT_T_BC3_UNORM, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, 0x35545844, 0x02, "DXT5", 0x80, 1 }, * { FORMAT_ATI1, GX2_SURFACE_FORMAT_T_BC4_UNORM, GL_COMPRESSED_RED_RGTC1, 0x31495441, 0x15, "ATI1", 0x40, 1 }, * { FORMAT_ATI2, GX2_SURFACE_FORMAT_T_BC5_UNORM, GL_COMPRESSED_RG_RGTC2, 0x32495441, 0x16, "ATI2", 0x80, 1 }, * { FORMAT_INVALID, GX2_SURFACE_FORMAT_INVALID, 0, 0xFFFFFFFF, 0x00, nullptr, 0x00, 0 } * };*/ public static byte[] SwizzleBc(byte[] data, int width, int height, int format, int tileMode, int pitch, int swizzle) { Gx2Surface sur = new Gx2Surface(); sur.width = width; sur.height = height; sur.tileMode = tileMode; sur.format = format; sur.swizzle = swizzle; sur.pitch = pitch; sur.data = data; sur.imageSize = data.Length; //return swizzleBC(sur); return(SwizzleSurface(sur, (Gx2SurfaceFormat)sur.format != Gx2SurfaceFormat.Gx2SurfaceFormatTcsR8G8B8A8Unorm & (Gx2SurfaceFormat)sur.format != Gx2SurfaceFormat.Gx2SurfaceFormatTcsR8G8B8A8Srgb)); }
public static byte[] SwizzleBc(Gx2Surface surface) { //std::vector<u8> result; //List<byte> result = new List<byte>(); //result.resize(surface->imageSize); //u8 *data = (u8*)surface->imagePtr; byte[] data = surface.data; byte[] result = new byte[surface.imageSize]; int width = surface.width / 4; int height = surface.height / 4; for (int y = 0; y < height; ++y) { for (int x = 0; x < width; ++x) { int bpp = GetFormatBpp(surface.format); int pos = 0; switch (surface.tileMode) { case 0: case 1: { // pos = surfaceAddrFromCoordLinear( // x, y, 0, 0, bpp, // surface->pitch, height, surface->depth, 0 // ); //printf("Unsupported tilemode %d\n", surface->tileMode); //exit(1); } break; case 2: case 3: { // pos = surfaceAddrFromCoordMicroTiled( // x, y, 0, bpp, surface->pitch, height, // surface->tileMode, 0, 0, 0, 0 // ); //printf("Unsupported tilemode %d\n", surface->tileMode); //exit(1); } break; default: { pos = SurfaceAddrFromCoordMacroTiled( x, y, 0, 0, bpp, surface.pitch, height, 1, (AddrTileMode)surface.tileMode, 0, 0, 0, (surface.swizzle >> 8) & 1, (surface.swizzle >> 9) & 3 ); } break; } int q = y * width + x; switch (surface.format) { case 0x31: case 0x34: case 0x234: case 0x431: { System.Array.Copy(data, pos, result, q * 8, 8); //memcpy(result.data() + q*8, data+pos, 8); } break; default: { System.Array.Copy(data, pos, result, q * 16, 16); //memcpy(result.data() + q*16, data+pos, 16); } break; } } } return(result); //memcpy(data, result.data(), result.size()); }
public static byte[] SwizzleSurface(Gx2Surface surface, bool isCompressed) { byte[] original = new byte[surface.data.Length]; surface.data.CopyTo(original, 0); int swizzle = ((surface.swizzle >> 8) & 1) + (((surface.swizzle >> 9) & 3) << 1); int blockSize; int width = surface.width; int height = surface.height; int format = GetBpp(surface.format); Console.WriteLine(((Gx2SurfaceFormat)surface.format).ToString()); if (isCompressed) { width /= 4; height /= 4; if ((Gx2SurfaceFormat)surface.format == Gx2SurfaceFormat.Gx2SurfaceFormatTBc1Unorm || (Gx2SurfaceFormat)surface.format == Gx2SurfaceFormat.Gx2SurfaceFormatTBc1Srgb || (Gx2SurfaceFormat)surface.format == Gx2SurfaceFormat.Gx2SurfaceFormatTBc4Unorm || (Gx2SurfaceFormat)surface.format == Gx2SurfaceFormat.Gx2SurfaceFormatTBc4Snorm) { blockSize = 8; } else { blockSize = 16; } } else { /*if ((GX2SurfaceFormat)surface.format == GX2SurfaceFormat.GX2_SURFACE_FORMAT_TC_R5_G5_B5_A1_UNORM) * { * blockSize = format / 4; * } * else*/ blockSize = format / 8; } for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { int pos = SurfaceAddrFromCoordMacroTiled(x, y, format, surface.pitch, swizzle); int size = (y * width + x) * blockSize; for (int k = 0; k < blockSize; k++) { if (pos + k >= original.Length || size + k >= surface.data.Length) { Console.WriteLine("Break Point " + size + " " + pos); break; } surface.data[size + k] = original[pos + k]; } } } return(surface.data); }