Exemple #1
0
        public static KtxFile Load(Stream s, bool readKeyValuePairs)
        {
            using (BinaryReader br = new BinaryReader(s))
            {
                KtxHeader header = ReadStruct <KtxHeader>(br);

                KtxKeyValuePair[] kvps = null;
                if (readKeyValuePairs)
                {
                    int keyValuePairBytesRead            = 0;
                    List <KtxKeyValuePair> keyValuePairs = new List <KtxKeyValuePair>();
                    while (keyValuePairBytesRead < header.BytesOfKeyValueData)
                    {
                        int             bytesRemaining = (int)(header.BytesOfKeyValueData - keyValuePairBytesRead);
                        KtxKeyValuePair kvp            = ReadNextKeyValuePair(br, out int read);
                        keyValuePairBytesRead += read;
                        keyValuePairs.Add(kvp);
                    }

                    kvps = keyValuePairs.ToArray();
                }
                else
                {
                    br.BaseStream.Seek(header.BytesOfKeyValueData, SeekOrigin.Current); // Skip over header data.
                }

                uint           numberOfFaces = Math.Max(1, header.NumberOfFaces);
                List <KtxFace> faces         = new List <KtxFace>((int)numberOfFaces);
                for (int i = 0; i < numberOfFaces; i++)
                {
                    faces.Add(new KtxFace(header.NumberOfMipmapLevels));
                }
                for (uint mipLevel = 0; mipLevel < header.NumberOfMipmapLevels; mipLevel++)
                {
                    uint imageSize = br.ReadUInt32();
                    // For cubemap textures, imageSize is actually the size of an individual face.
                    bool isCubemap = header.NumberOfFaces == 6 && header.NumberOfArrayElements == 0;
                    for (uint face = 0; face < numberOfFaces; face++)
                    {
                        byte[] faceData = br.ReadBytes((int)imageSize);
                        faces[(int)face].Mipmaps[mipLevel] = new KtxMipmap(imageSize, faceData, header.PixelWidth / (uint)(Math.Pow(2, mipLevel)), header.PixelHeight / (uint)(Math.Pow(2, mipLevel)));
                        uint cubePadding = 0u;
                        if (isCubemap)
                        {
                            cubePadding = 3 - ((imageSize + 3) % 4);
                        }
                        br.BaseStream.Seek(cubePadding, SeekOrigin.Current);
                    }

                    uint mipPaddingBytes = 3 - ((imageSize + 3) % 4);
                    br.BaseStream.Seek(mipPaddingBytes, SeekOrigin.Current);
                }

                return(new KtxFile(header, kvps, faces.ToArray()));
            }
        }
Exemple #2
0
        public static KtxFile Load(Stream s, bool readKeyValuePairs)
        {
            using (BinaryReader br = new BinaryReader(s))
            {
                KtxHeader header = ReadStruct <KtxHeader>(br);

                KtxKeyValuePair[] kvps = null;
                if (readKeyValuePairs)
                {
                    int keyValuePairBytesRead            = 0;
                    List <KtxKeyValuePair> keyValuePairs = new List <KtxKeyValuePair>();
                    while (keyValuePairBytesRead < header.BytesOfKeyValueData)
                    {
                        int             bytesRemaining = (int)(header.BytesOfKeyValueData - keyValuePairBytesRead);
                        KtxKeyValuePair kvp            = ReadNextKeyValuePair(br, out int read);
                        keyValuePairBytesRead += read;
                        keyValuePairs.Add(kvp);
                    }

                    kvps = keyValuePairs.ToArray();
                }
                else
                {
                    br.BaseStream.Seek(header.BytesOfKeyValueData, SeekOrigin.Current); // Skip over header data.
                }

                uint numberOfMipmapLevels  = Math.Max(1, header.NumberOfMipmapLevels);
                uint numberOfArrayElements = Math.Max(1, header.NumberOfArrayElements);
                uint numberOfFaces         = Math.Max(1, header.NumberOfFaces);

                uint baseWidth  = Math.Max(1, header.PixelWidth);
                uint baseHeight = Math.Max(1, header.PixelHeight);
                uint baseDepth  = Math.Max(1, header.PixelDepth);

                KtxMipmapLevel[] images = new KtxMipmapLevel[numberOfMipmapLevels];
                for (int mip = 0; mip < numberOfMipmapLevels; mip++)
                {
                    uint mipWidth  = Math.Max(1, baseWidth / (uint)(Math.Pow(2, mip)));
                    uint mipHeight = Math.Max(1, baseHeight / (uint)(Math.Pow(2, mip)));
                    uint mipDepth  = Math.Max(1, baseDepth / (uint)(Math.Pow(2, mip)));

                    uint imageSize                  = br.ReadUInt32();
                    uint arrayElementSize           = imageSize / numberOfArrayElements;
                    KtxArrayElement[] arrayElements = new KtxArrayElement[numberOfArrayElements];
                    for (int arr = 0; arr < numberOfArrayElements; arr++)
                    {
                        uint      faceSize = arrayElementSize / numberOfFaces;
                        KtxFace[] faces    = new KtxFace[numberOfFaces];
                        for (int face = 0; face < numberOfFaces; face++)
                        {
                            faces[face] = new KtxFace(br.ReadBytes((int)faceSize));
                        }

                        arrayElements[arr] = new KtxArrayElement(faces);
                    }

                    images[mip] = new KtxMipmapLevel(
                        mipWidth,
                        mipHeight,
                        mipDepth,
                        imageSize,
                        arrayElementSize,
                        arrayElements);

                    uint mipPaddingBytes = 3 - ((imageSize + 3) % 4);
                    br.BaseStream.Seek(mipPaddingBytes, SeekOrigin.Current);
                }

                return(new KtxFile(header, kvps, images));
            }
        }