public Texture2D ReadTexture(BinaryReader reader, TEXDescriptor desc, string saveFilePath, string textureName)
        {
            // Verify if index is valid (some entries can be nulled out)
            // We check for 0 specifically because garbage can be store in the
            // first few entries of the file.
            // TPL can have null entries so this is actually correct to the format
            if (desc.isNullEntry != 0)
            {
                return(null);
            }

            // We use Try as GxTextureFormatCodec.GetCodec() can return an error if the type is invalid
            try
            {
                GxTextureFormatCodec codec = GxTextureFormatCodec.GetCodec((GxTextureFormat)desc.format);
                reader.BaseStream.Position = desc.dataPtr;
                byte[] texRaw  = reader.GetBytes(codec.CalcTextureSize(desc.width, desc.height));
                byte[] texRGBA = new byte[4 * desc.width * desc.height]; // RGBA (4 bytes) * w * h
                codec.DecodeTexture(texRGBA, 0, desc.width, desc.height, desc.width * 4, texRaw, 0, null, 0);

                // Reconstruct Texture using Unity's format
                Texture2D texture = new Texture2D(desc.width, desc.height);
                for (int y = 0; y < desc.height; y++)
                {
                    for (int x = 0; x < desc.width; x++)
                    {
                        // Invert Y because LibGXTexture returns array upside-down?
                        // ei 'x, (desc.width - y)' instead of 'x, y'
                        texture.SetPixel(x, (desc.width - y), new Color32(
                                             texRGBA[(y * desc.width + x) * 4 + 0],
                                             texRGBA[(y * desc.width + x) * 4 + 1],
                                             texRGBA[(y * desc.width + x) * 4 + 2],
                                             texRGBA[(y * desc.width + x) * 4 + 3]));
                    }
                }

                string assetPath  = string.Format("{0}/tex_{1}.png", saveFilePath, textureName).PathToUnityPath();
                byte[] imageBytes = texture.EncodeToPNG();
                DestroyImmediate(texture);

                using (BinaryWriter writer = new BinaryWriter(File.Create(assetPath, imageBytes.Length)))
                {
                    writer.Write(imageBytes);
                }

                AssetDatabase.ImportAsset(assetPath, ImportAssetOptions.ForceUpdate);
                AssetDatabase.Refresh(ImportAssetOptions.Default);
                Texture2D tex = (Texture2D)AssetDatabase.LoadAssetAtPath(assetPath, typeof(Texture2D));
                return(tex);
            }
            catch
            {
                Debug.LogErrorFormat("GxTextureFormatCodec.GetCodec() failed to find format [0x{0}]", desc.format.ToString("X2"));
                return(null);
            }
        }
Exemplo n.º 2
0
        public bool ReadTextureFromTPL(BinaryReader reader, int index, out Texture2D texture, string name, bool saveToDisk)
        {
            // If index is invalid
            if (index > numDescriptors)
            {
                throw new System.IndexOutOfRangeException(string.Format("Index must be less than or equal to {0}!", numDescriptors));
            }
            else if (index < 0)
            {
                throw new System.IndexOutOfRangeException("Index must be greater than 0!");
            }

            // Load Texture Descriptor at index
            TEXDescriptor desc = descriptorArray[index];

            // Verify if index is valid (some entries can be nulled out)
            // We check for 0 specifically because garbage can be store in the
            // first few entries of the file.
            if (desc.isNullEntry != 0)
            {
                texture = null;
                return(false);
            }

            // We use Try as GxTextureFormatCodec.GetCodec() can return an error if the type is invalid
            try
            {
                GxTextureFormatCodec codec = GxTextureFormatCodec.GetCodec((GxTextureFormat)desc.format);
                reader.BaseStream.Position = desc.dataPtr;
                byte[] texRaw  = reader.GetBytes(codec.CalcTextureSize(desc.width, desc.height));
                byte[] texRGBA = new byte[4 * desc.width * desc.height]; // RGBA (4 bytes) * w * h
                codec.DecodeTexture(texRGBA, 0, desc.width, desc.height, desc.width * 4, texRaw, 0, null, 0);

                // Reconstruct Texture using Unity's format
                texture = new Texture2D(desc.width, desc.height);
                for (int y = 0; y < desc.height; y++)
                {
                    for (int x = 0; x < desc.width; x++)
                    {
                        // Invert Y because LibGXTexture return array upside-down
                        // ei 'x, (desc.width - y)' instead of 'x, y'
                        texture.SetPixel(x, (desc.width - y), new Color32(
                                             texRGBA[(y * desc.width + x) * 4 + 0],
                                             texRGBA[(y * desc.width + x) * 4 + 1],
                                             texRGBA[(y * desc.width + x) * 4 + 2],
                                             texRGBA[(y * desc.width + x) * 4 + 3]));
                    }
                }

                if (saveToDisk)
                {
                    Debug.LogFormat("Saved {0} to path {1}", name, PersistantDataPath(""));
                    SaveBytes(string.Format("{0}.png", name), texture.EncodeToPNG());
                }

                return(true);
            }
            catch
            {
                Debug.LogErrorFormat("GxTextureFormatCodec.GetCodec() failed to find format [{0}]", desc.format.ToString("X"));
                texture = null;
                return(false);
            }
        }