Beispiel #1
0
        private IBcBlockDecoder GetDecoder(GlInternalFormat format)
        {
            switch (format)
            {
            case GlInternalFormat.GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
                return(new Bc1NoAlphaDecoder());

            case GlInternalFormat.GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
                return(new Bc1ADecoder());

            case GlInternalFormat.GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
                return(new Bc2Decoder());

            case GlInternalFormat.GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
                return(new Bc3Decoder());

            case GlInternalFormat.GL_COMPRESSED_RED_RGTC1_EXT:
                return(new Bc4Decoder(OutputOptions.redAsLuminance));

            case GlInternalFormat.GL_COMPRESSED_RED_GREEN_RGTC2_EXT:
                return(new Bc5Decoder());

            case GlInternalFormat.GL_COMPRESSED_RGBA_BPTC_UNORM_ARB:
                return(new Bc7Decoder());

            // TODO: Not sure what to do with SRGB input.
            case GlInternalFormat.GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB:
                return(new Bc7Decoder());

            default:
                return(null);
            }
        }
Beispiel #2
0
        /// <summary>
        /// KtxHeader constructor for 2d texture
        /// </summary>
        /// <param name="glDataType">GlDataType</param>
        /// <param name="glPixelFormat">GlPixelFormat</param>
        /// <param name="glInternalFormat">GlInternalFormat</param>
        /// <param name="width">Width</param>
        /// <param name="height">Height</param>
        /// <param name="mipmapCount">Mipmap count</param>
        /// <param name="metadata">Metadata</param>
        public KtxHeader(GlDataType glDataType, GlPixelFormat glPixelFormat, GlInternalFormat glInternalFormat, uint width, uint height, uint mipmapCount, Dictionary <string, MetadataValue> metadata)
        {
            this.isInputLittleEndian = true;

            this.glDataType   = glDataType;
            this.glTypeAsUint = (uint)this.glDataType;

            this.glTypeSizeAsUint = Common.GlTypeToSize[glDataType];

            this.glFormat       = (glDataType != GlDataType.Compressed) ? glPixelFormat : 0;
            this.glFormatAsUint = (uint)this.glFormat;

            this.glInternalFormat       = glInternalFormat;
            this.glInternalFormatAsUint = (uint)this.glInternalFormat;

            this.glPixelFormat = glPixelFormat;
            this.glBaseInternalFormatAsUint = (uint)this.glPixelFormat;

            this.pixelWidth  = width;
            this.pixelHeight = height;

            // For 2d textures these values must be 0
            this.pixelDepth            = 0;
            this.numberOfArrayElements = 0;

            // For non cubemaps this should be 1
            this.numberOfFaces = 1;

            this.numberOfMipmapLevels = mipmapCount;

            this.metadataDictionary = metadata;
        }
Beispiel #3
0
        private bool IsSupportedRawFormat(GlInternalFormat format)
        {
            switch (format)
            {
            case GlInternalFormat.GL_R8:
            case GlInternalFormat.GL_RG8:
            case GlInternalFormat.GL_RGB8:
            case GlInternalFormat.GL_RGBA8:
                return(true);

            default:
                return(false);
            }
        }
Beispiel #4
0
        public static KtxHeader InitializeCompressed(int width, int height, GlInternalFormat internalFormat, GLFormat baseInternalFormat)
        {
            KtxHeader   header = new KtxHeader();
            Span <byte> id     = stackalloc byte[] { 0xAB, 0x4B, 0x54, 0x58, 0x20, 0x31, 0x31, 0xBB, 0x0D, 0x0A, 0x1A, 0x0A };

            for (int i = 0; i < id.Length; i++)
            {
                header.Identifier[i] = id[i];
            }
            header.Endianness           = 0x04030201;
            header.PixelWidth           = (uint)width;
            header.PixelHeight          = (uint)height;
            header.GlType               = 0;
            header.GlTypeSize           = 1;
            header.GlFormat             = 0;
            header.GlInternalFormat     = internalFormat;
            header.GlBaseInternalFormat = baseInternalFormat;

            return(header);
        }
Beispiel #5
0
        private IRawDecoder GetRawDecoder(GlInternalFormat format)
        {
            switch (format)
            {
            case GlInternalFormat.GL_R8:
                return(new RawRDecoder(OutputOptions.redAsLuminance));

            case GlInternalFormat.GL_RG8:
                return(new RawRGDecoder());

            case GlInternalFormat.GL_RGB8:
                return(new RawRGBDecoder());

            case GlInternalFormat.GL_RGBA8:
                return(new RawRGBADecoder());

            default:
                return(null);
            }
        }
Beispiel #6
0
        /// <summary>
        /// Create new 2d KtxStructure from existing data
        /// </summary>
        /// <param name="glDataType">GlDataType</param>
        /// <param name="glPixelFormat">GlPixelFormat</param>
        /// <param name="glInternalFormat">GlInternalFormat</param>
        /// <param name="width">Width</param>
        /// <param name="height">Height</param>
        /// <param name="textureDatas">Texture datas</param>
        /// <param name="metadata">metadata</param>
        /// <returns>KtxStructure</returns>
        public static KtxStructure Create(GlDataType glDataType, GlPixelFormat glPixelFormat, GlInternalFormat glInternalFormat, uint width, uint height, List <byte[]> textureDatas, Dictionary <string, MetadataValue> metadata)
        {
            KtxHeader      header      = new KtxHeader(glDataType, glPixelFormat, glInternalFormat, width, height, (uint)textureDatas.Count, metadata);
            KtxTextureData textureData = new KtxTextureData(textureDatas);

            return(new KtxStructure(header, textureData));
        }
        public static VkFormat vkGetFormatFromOpenGLInternalFormat(GlInternalFormat internalFormat, GLFormat format, GLType glType)
        {
            switch (internalFormat)
            {
            //
            // Packed formats
            //

            case GlInternalFormat.GL_RGBA4:
                if (format == GLFormat.GL_RGBA)
                {
                    return(VkFormat.R4g4b4a4UnormPack16);
                }
                else
                {
                    return(VkFormat.B4g4r4a4UnormPack16);
                }

            case GlInternalFormat.GL_RGB565:
                if (glType == GLType.GL_UNSIGNED_SHORT_5_6_5)
                {
                    return(VkFormat.R5g6b5UnormPack16);
                }
                else
                {
                    return(VkFormat.B5g6r5UnormPack16);
                }

            case GlInternalFormat.GL_RGB5_A1:
                if (format == GLFormat.GL_RGBA)
                {
                    return(VkFormat.R5g5b5a1UnormPack16);
                }
                else if (glType == GLType.GL_UNSIGNED_SHORT_5_5_5_1)
                {
                    return(VkFormat.B5g5r5a1UnormPack16);
                }
                else
                {
                    return(VkFormat.A1r5g5b5UnormPack16);
                }

            //
            // Raw formats 8 bits
            //
            case GlInternalFormat.GL_R8:
                return(VkFormat.R8Unorm);

            case GlInternalFormat.GL_R8_SNORM:
                return(VkFormat.R8Snorm);

            case GlInternalFormat.GL_R8UI:
                return(VkFormat.R8Uint);

            case GlInternalFormat.GL_R8I:
                return(VkFormat.R8Sint);

            case GlInternalFormat.GL_RG8:
                return(VkFormat.R8g8Unorm);

            case GlInternalFormat.GL_RG8_SNORM:
                return(VkFormat.R8g8Snorm);

            case GlInternalFormat.GL_RG8UI:
                return(VkFormat.R8g8Uint);

            case GlInternalFormat.GL_RG8I:
                return(VkFormat.R8g8Sint);

            case GlInternalFormat.GL_RGB8:
                if (format == GLFormat.GL_RGB)
                {
                    return(VkFormat.R8g8b8Unorm);
                }
                else
                {
                    return(VkFormat.B8g8r8Unorm);
                }

            case GlInternalFormat.GL_RGB8_SNORM:
                if (format == GLFormat.GL_RGB)
                {
                    return(VkFormat.R8g8b8Snorm);
                }
                else
                {
                    return(VkFormat.B8g8r8Snorm);
                }

            case GlInternalFormat.GL_RGB8UI:
                if (format == GLFormat.GL_RGB)
                {
                    return(VkFormat.R8g8b8Uint);
                }
                else
                {
                    return(VkFormat.B8g8r8Uint);
                }

            case GlInternalFormat.GL_RGB8I:
                if (format == GLFormat.GL_RGB)
                {
                    return(VkFormat.R8g8b8Sint);
                }
                else
                {
                    return(VkFormat.B8g8r8Sint);
                }

            case GlInternalFormat.GL_RGBA8:
                if (format == GLFormat.GL_RGBA)
                {
                    return(VkFormat.R8g8b8a8Unorm);
                }
                else
                {
                    return(VkFormat.B8g8r8a8Unorm);
                }

            case GlInternalFormat.GL_RGBA8_SNORM:
                if (format == GLFormat.GL_RGBA)
                {
                    return(VkFormat.R8g8b8a8Snorm);
                }
                else
                {
                    return(VkFormat.B8g8r8a8Snorm);
                }

            case GlInternalFormat.GL_RGBA8UI:
                if (format == GLFormat.GL_RGBA)
                {
                    return(VkFormat.R8g8b8a8Uint);
                }
                else
                {
                    return(VkFormat.B8g8r8a8Uint);
                }

            case GlInternalFormat.GL_RGBA8I:
                if (format == GLFormat.GL_RGBA)
                {
                    return(VkFormat.R8g8b8a8Sint);
                }
                else
                {
                    return(VkFormat.B8g8r8a8Sint);
                }

            //
            // 10 bit color 2 alpha packed formats
            //
            case GlInternalFormat.GL_RGB10_A2:
                if (format == GLFormat.GL_RGBA)
                {
                    return(VkFormat.A2r10g10b10SnormPack32);
                }
                else
                {
                    return(VkFormat.A2b10g10r10SnormPack32);
                }

            case GlInternalFormat.GL_RGB10_A2UI:
                if (format == GLFormat.GL_RGBA)
                {
                    return(VkFormat.A2r10g10b10UintPack32);
                }
                else
                {
                    return(VkFormat.A2b10g10r10UintPack32);
                }

            //
            // Raw formats 16 bits
            //

            case GlInternalFormat.GL_R16:
                return(VkFormat.R16Unorm);

            case GlInternalFormat.GL_R16_SNORM:
                return(VkFormat.R16Snorm);

            case GlInternalFormat.GL_R16UI:
                return(VkFormat.R16Uint);

            case GlInternalFormat.GL_R16I:
                return(VkFormat.R16Sint);

            case GlInternalFormat.GL_R16F:
                return(VkFormat.R16Sfloat);

            case GlInternalFormat.GL_RG16:
                return(VkFormat.R16g16Unorm);

            case GlInternalFormat.GL_RG16_SNORM:
                return(VkFormat.R16g16Snorm);

            case GlInternalFormat.GL_RG16UI:
                return(VkFormat.R16g16Uint);

            case GlInternalFormat.GL_RG16I:
                return(VkFormat.R16g16Sint);

            case GlInternalFormat.GL_RG16F:
                return(VkFormat.R16g16Sfloat);

            case GlInternalFormat.GL_RGB16:
                return(VkFormat.R16g16b16Unorm);

            case GlInternalFormat.GL_RGB16_SNORM:
                return(VkFormat.R16g16b16Snorm);

            case GlInternalFormat.GL_RGB16UI:
                return(VkFormat.R16g16b16Uint);

            case GlInternalFormat.GL_RGB16I:
                return(VkFormat.R16g16b16Sint);

            case GlInternalFormat.GL_RGB16F:
                return(VkFormat.R16g16b16Sfloat);

            case GlInternalFormat.GL_RGBA16:
                return(VkFormat.R16g16b16a16Unorm);

            case GlInternalFormat.GL_RGBA16_SNORM:
                return(VkFormat.R16g16b16a16Snorm);

            case GlInternalFormat.GL_RGBA16UI:
                return(VkFormat.R16g16b16a16Uint);

            case GlInternalFormat.GL_RGBA16I:
                return(VkFormat.R16g16b16a16Sint);

            case GlInternalFormat.GL_RGBA16F:
                return(VkFormat.R16g16b16a16Sfloat);

            //
            // Raw formats 32 bits
            //

            case GlInternalFormat.GL_R32UI:
                return(VkFormat.R32Uint);

            case GlInternalFormat.GL_R32I:
                return(VkFormat.R32Sint);

            case GlInternalFormat.GL_R32F:
                return(VkFormat.R32Sfloat);

            case GlInternalFormat.GL_RG32UI:
                return(VkFormat.R32g32Uint);

            case GlInternalFormat.GL_RG32I:
                return(VkFormat.R32g32Sint);

            case GlInternalFormat.GL_RG32F:
                return(VkFormat.R32g32Sfloat);

            case GlInternalFormat.GL_RGB32UI:
                return(VkFormat.R32g32b32Uint);

            case GlInternalFormat.GL_RGB32I:
                return(VkFormat.R32g32b32Sint);

            case GlInternalFormat.GL_RGB32F:
                return(VkFormat.R32g32b32Sfloat);

            case GlInternalFormat.GL_RGBA32UI:
                return(VkFormat.R32g32b32a32Uint);

            case GlInternalFormat.GL_RGBA32I:
                return(VkFormat.R32g32b32a32Sint);

            case GlInternalFormat.GL_RGBA32F:
                return(VkFormat.R32g32b32a32Sfloat);

            //
            // Depth formats
            //

            case GlInternalFormat.GL_DEPTH_COMPONENT16:
                return(VkFormat.D16Unorm);

            case GlInternalFormat.GL_DEPTH_COMPONENT24:
                return(VkFormat.X8D24UnormPack32);

            case GlInternalFormat.GL_DEPTH_COMPONENT32F:
                return(VkFormat.D32Sfloat);

            case GlInternalFormat.GL_STENCIL_INDEX8:
                return(VkFormat.S8Uint);

            case GlInternalFormat.GL_DEPTH24_STENCIL8:
                return(VkFormat.D24UnormS8Uint);

            case GlInternalFormat.GL_DEPTH32F_STENCIL8:
                return(VkFormat.D32SfloatS8Uint);

            //
            // S3TC/DXT/BC
            //
            case GlInternalFormat.GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
                return(VkFormat.Bc1RgbUnormBlock);

            case GlInternalFormat.GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
                return(VkFormat.Bc1RgbaUnormBlock);

            case GlInternalFormat.GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
                return(VkFormat.Bc1RgbSrgbBlock);

            case GlInternalFormat.GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
                return(VkFormat.Bc1RgbaSrgbBlock);

            case GlInternalFormat.GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
                return(VkFormat.Bc2UnormBlock);

            case GlInternalFormat.GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
                return(VkFormat.Bc2SrgbBlock);


            case GlInternalFormat.GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
                return(VkFormat.Bc3UnormBlock);

            case GlInternalFormat.GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
                return(VkFormat.Bc3SrgbBlock);

            case  GlInternalFormat.GL_COMPRESSED_RED_RGTC1_EXT:
                return(VkFormat.Bc4UnormBlock);

            case GlInternalFormat.GL_COMPRESSED_SIGNED_RED_RGTC1_EXT:
                return(VkFormat.Bc4SnormBlock);

            case GlInternalFormat.GL_COMPRESSED_RED_GREEN_RGTC2_EXT:
                return(VkFormat.Bc5UnormBlock);

            case GlInternalFormat.GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT:
                return(VkFormat.Bc5SnormBlock);

            case GlInternalFormat.GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB:
                return(VkFormat.Bc6hUfloatBlock);

            case GlInternalFormat.GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB:
                return(VkFormat.Bc6hSfloatBlock);

            case GlInternalFormat.GL_COMPRESSED_RGBA_BPTC_UNORM_ARB:
                return(VkFormat.Bc7UnormBlock);

            case GlInternalFormat.GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB:
                return(VkFormat.Bc7SrgbBlock);

            //
            // ETC
            //
            case GlInternalFormat.GL_ETC1_RGB8_OES:
                return(VkFormat.Etc2R8g8b8UnormBlock);

            case GlInternalFormat.GL_COMPRESSED_RGB8_ETC2:
                return(VkFormat.Etc2R8g8b8UnormBlock);

            case GlInternalFormat.GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
                return(VkFormat.Etc2R8g8b8a1UnormBlock);

            case GlInternalFormat.GL_COMPRESSED_RGBA8_ETC2_EAC:
                return(VkFormat.Etc2R8g8b8a8UnormBlock);

            case GlInternalFormat.GL_COMPRESSED_SRGB8_ETC2:
                return(VkFormat.Etc2R8g8b8SrgbBlock);

            case GlInternalFormat.GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
                return(VkFormat.Etc2R8g8b8a1SrgbBlock);

            case GlInternalFormat.GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
                return(VkFormat.Etc2R8g8b8a8SrgbBlock);

            case GlInternalFormat.GL_COMPRESSED_R11_EAC:
                return(VkFormat.EacR11UnormBlock);

            case GlInternalFormat.GL_COMPRESSED_RG11_EAC:
                return(VkFormat.EacR11g11UnormBlock);

            case GlInternalFormat.GL_COMPRESSED_SIGNED_R11_EAC:
                return(VkFormat.EacR11SnormBlock);

            case GlInternalFormat.GL_COMPRESSED_SIGNED_RG11_EAC:
                return(VkFormat.EacR11g11SnormBlock);

            //
            // ASTC
            //
            case GlInternalFormat.GL_COMPRESSED_RGBA_ASTC_4x4_KHR:
                return(VkFormat.Astc4x4UnormBlock);

            case GlInternalFormat.GL_COMPRESSED_RGBA_ASTC_5x4_KHR:
                return(VkFormat.Astc5x4UnormBlock);

            case GlInternalFormat.GL_COMPRESSED_RGBA_ASTC_5x5_KHR:
                return(VkFormat.Astc5x5UnormBlock);

            case GlInternalFormat.GL_COMPRESSED_RGBA_ASTC_6x5_KHR:
                return(VkFormat.Astc6x5UnormBlock);

            case GlInternalFormat.GL_COMPRESSED_RGBA_ASTC_6x6_KHR:
                return(VkFormat.Astc6x6UnormBlock);

            case GlInternalFormat.GL_COMPRESSED_RGBA_ASTC_8x5_KHR:
                return(VkFormat.Astc8x5UnormBlock);

            case GlInternalFormat.GL_COMPRESSED_RGBA_ASTC_8x6_KHR:
                return(VkFormat.Astc8x6UnormBlock);

            case GlInternalFormat.GL_COMPRESSED_RGBA_ASTC_8x8_KHR:
                return(VkFormat.Astc8x8UnormBlock);

            case GlInternalFormat.GL_COMPRESSED_RGBA_ASTC_10x5_KHR:
                return(VkFormat.Astc10x5UnormBlock);

            case GlInternalFormat.GL_COMPRESSED_RGBA_ASTC_10x6_KHR:
                return(VkFormat.Astc10x6UnormBlock);

            case GlInternalFormat.GL_COMPRESSED_RGBA_ASTC_10x8_KHR:
                return(VkFormat.Astc10x8UnormBlock);

            case GlInternalFormat.GL_COMPRESSED_RGBA_ASTC_10x10_KHR:
                return(VkFormat.Astc10x10UnormBlock);

            case GlInternalFormat.GL_COMPRESSED_RGBA_ASTC_12x10_KHR:
                return(VkFormat.Astc12x10UnormBlock);

            case GlInternalFormat.GL_COMPRESSED_RGBA_ASTC_12x12_KHR:
                return(VkFormat.Astc12x12UnormBlock);

            case GlInternalFormat.GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
                return(VkFormat.Astc4x4SrgbBlock);

            case GlInternalFormat.GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
                return(VkFormat.Astc5x4SrgbBlock);

            case GlInternalFormat.GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
                return(VkFormat.Astc5x5SrgbBlock);

            case GlInternalFormat.GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
                return(VkFormat.Astc6x5SrgbBlock);

            case GlInternalFormat.GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
                return(VkFormat.Astc6x6SrgbBlock);

            case GlInternalFormat.GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
                return(VkFormat.Astc8x5SrgbBlock);

            case GlInternalFormat.GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
                return(VkFormat.Astc8x6SrgbBlock);

            case GlInternalFormat.GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
                return(VkFormat.Astc8x8SrgbBlock);

            case GlInternalFormat.GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
                return(VkFormat.Astc10x5SrgbBlock);

            case GlInternalFormat.GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
                return(VkFormat.Astc10x6SrgbBlock);

            case GlInternalFormat.GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
                return(VkFormat.Astc10x8SrgbBlock);

            case GlInternalFormat.GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
                return(VkFormat.Astc10x10SrgbBlock);

            case GlInternalFormat.GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
                return(VkFormat.Astc12x10SrgbBlock);

            case GlInternalFormat.GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
                return(VkFormat.Astc12x12SrgbBlock);

            default: return(VkFormat.Undefined);
            }
        }
Beispiel #8
0
        /// <summary>
        /// KtxHeader constructor
        /// </summary>
        /// <param name="stream">Stream for reading</param>
        public KtxHeader(Stream stream)
        {
            // Skip first 12 bytes since they only contain identifier
            stream.Seek(12, SeekOrigin.Begin);

            // Read endianness as bytes
            byte[] endiannessBytes = new byte[4];
            int    bytesRead       = stream.Read(buffer: endiannessBytes, offset: 0, count: endiannessBytes.Length);

            if (bytesRead != 4)
            {
                throw new InvalidOperationException("Cannot read enough bytes from stream!");
            }

            if (!Common.littleEndianAsBytes.SequenceEqual(endiannessBytes) && !Common.bigEndianAsBytes.SequenceEqual(endiannessBytes))
            {
                throw new InvalidOperationException("Endianness info in header is not valid!");
            }

            this.isInputLittleEndian = Common.littleEndianAsBytes.SequenceEqual(endiannessBytes);

            // Turn endianness as bytes to uint
            this.endiannessValue = BitConverter.ToUInt32(endiannessBytes, 0);

            // See if following uint reads need endian swap
            bool shouldSwapEndianness = (this.endiannessValue != Common.expectedEndianValue);

            // Use the stream in a binary reader.
            using (BinaryReader reader = new BinaryReader(stream, Encoding.UTF8, leaveOpen: true))
            {
                // Swap endianness for every KTX variable if needed

                this.glTypeAsUint = shouldSwapEndianness ? KtxBitFiddling.SwapEndian(reader.ReadUInt32()) : reader.ReadUInt32();
                if (GlDataType.IsDefined(typeof(GlDataType), this.glTypeAsUint))
                {
                    this.glDataType = (GlDataType)this.glTypeAsUint;
                }
                else
                {
                    this.glDataType = GlDataType.NotKnown;
                }

                this.glTypeSizeAsUint = shouldSwapEndianness ? KtxBitFiddling.SwapEndian(reader.ReadUInt32()) : reader.ReadUInt32();

                this.glFormatAsUint = shouldSwapEndianness ? KtxBitFiddling.SwapEndian(reader.ReadUInt32()) : reader.ReadUInt32();
                if (GlPixelFormat.IsDefined(typeof(GlPixelFormat), this.glFormatAsUint))
                {
                    this.glFormat = (GlPixelFormat)this.glFormatAsUint;
                }
                else
                {
                    this.glFormat = GlPixelFormat.NotKnown;
                }

                this.glInternalFormatAsUint = shouldSwapEndianness ? KtxBitFiddling.SwapEndian(reader.ReadUInt32()) : reader.ReadUInt32();
                if (GlInternalFormat.IsDefined(typeof(GlInternalFormat), this.glInternalFormatAsUint))
                {
                    this.glInternalFormat = (GlInternalFormat)this.glInternalFormatAsUint;
                }
                else
                {
                    this.glInternalFormat = GlInternalFormat.NotKnown;
                }

                this.glBaseInternalFormatAsUint = shouldSwapEndianness ? KtxBitFiddling.SwapEndian(reader.ReadUInt32()) : reader.ReadUInt32();
                if (GlPixelFormat.IsDefined(typeof(GlPixelFormat), this.glBaseInternalFormatAsUint))
                {
                    this.glPixelFormat = (GlPixelFormat)this.glBaseInternalFormatAsUint;
                }
                else
                {
                    this.glPixelFormat = GlPixelFormat.NotKnown;
                }

                this.pixelWidth = shouldSwapEndianness ? KtxBitFiddling.SwapEndian(reader.ReadUInt32()) : reader.ReadUInt32();

                this.pixelHeight = shouldSwapEndianness ? KtxBitFiddling.SwapEndian(reader.ReadUInt32()) : reader.ReadUInt32();

                this.pixelDepth = shouldSwapEndianness ? KtxBitFiddling.SwapEndian(reader.ReadUInt32()) : reader.ReadUInt32();

                this.numberOfArrayElements = shouldSwapEndianness ? KtxBitFiddling.SwapEndian(reader.ReadUInt32()) : reader.ReadUInt32();

                this.numberOfFaces = shouldSwapEndianness ? KtxBitFiddling.SwapEndian(reader.ReadUInt32()) : reader.ReadUInt32();

                this.numberOfMipmapLevels = shouldSwapEndianness ? KtxBitFiddling.SwapEndian(reader.ReadUInt32()) : reader.ReadUInt32();

                this.bytesOfKeyValueData = shouldSwapEndianness ? KtxBitFiddling.SwapEndian(reader.ReadUInt32()) : reader.ReadUInt32();

                // Check that bytesOfKeyValueData is mod 4
                if (this.bytesOfKeyValueData % 4 != 0)
                {
                    throw new InvalidOperationException(ErrorGen.Modulo4Error(nameof(this.bytesOfKeyValueData), this.bytesOfKeyValueData));
                }

                this.metadataDictionary = ParseMetadata(reader.ReadBytes((int)this.bytesOfKeyValueData), shouldSwapEndianness);
            }
        }