/// <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)); }
/// <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; }
public KtxHeader( KtxEndianness endianness, GlType glType, uint glTypeSize, GlPixelFormat glFormat, GlInternalPixelFormat glInternalFormat, GlBaseInternalPixelFormat glBaseInternalFormat, uint width, uint height, uint pixelDepth, uint numberOfArrayElements, uint numberOfFaces, uint numberOfMipmapLevels, uint bytesOfKeyValueData) { this.Endianness = endianness; this.GlTypeParameter = glType; this.GlTypeSize = glTypeSize; this.GlFormat = glFormat; this.GlInternalFormat = glInternalFormat; this.GlBaseInternalFormat = glBaseInternalFormat; this.Width = width; this.Height = height; this.PixelDepth = pixelDepth; this.NumberOfArrayElements = numberOfArrayElements; this.NumberOfFaces = numberOfFaces; this.NumberOfMipmapLevels = numberOfMipmapLevels; this.BytesOfKeyValueData = bytesOfKeyValueData; }
/// <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); } }