public static HwTexture FromData(BinaryReader reader) { var header = new TextureHeader(); // 32 byte texture header header.Type = (BaseTextureType)reader.ReadByte(); // 0 _ = reader.ReadByte(); // 1 header.Width = reader.ReadUInt16(); // 2 header.Height = reader.ReadUInt16(); // 4 header.TexArraySliceCount = 1; header.Tex3DDepth = 1; switch (header.Type) { case BaseTextureType._2D: case BaseTextureType.CubeMap: _ = reader.ReadUInt16(); break; case BaseTextureType._3D: header.Tex3DDepth = 1u << reader.ReadByte(); _ = reader.ReadByte(); break; case BaseTextureType._2DArray: header.TexArraySliceCount = reader.ReadUInt16(); break; default: throw new NotImplementedException("Unknown texture type"); } header.MipCount = reader.ReadByte(); // 8 header.PixelFormat = (BasePixelFormat)reader.ReadByte(); // 9 header.Unknown1 = reader.ReadByte(); // 10 header.Unknown2 = reader.ReadByte(); // 11 header.Unknown3 = reader.ReadByte(); // 12 header.Flags = reader.ReadByte(); // 13 header.Unknown4 = reader.ReadByte(); // 14 Something to do with mips. Autogen? header.Unknown5 = reader.ReadByte(); // 15 header.ResourceGUID = new BaseGGUUID().FromData(reader); // 16 var x = new HwTexture(); x.Header = header; uint hwTextureSize = reader.ReadUInt32(); x.HwTextureData = reader.ReadBytesStrict(hwTextureSize); return(x); }
public static HwTexture FromData(BinaryReader reader, GameType gameType) { var texture = new HwTexture(); var header = new TextureHeader(); // 32 byte texture header header.Type = (BaseTextureType)reader.ReadByte(); // 0 _ = reader.ReadByte(); // 1 header.Width = reader.ReadUInt16(); // 2 header.Height = reader.ReadUInt16(); // 4 header.ArraySliceCount = 0; header.Depth3D = 0; switch (header.Type) { case BaseTextureType._2D: case BaseTextureType.CubeMap: _ = reader.ReadUInt16(); break; case BaseTextureType._3D: header.Depth3D = 1u << reader.ReadByte(); _ = reader.ReadByte(); break; case BaseTextureType._2DArray: header.ArraySliceCount = reader.ReadUInt16(); break; default: throw new NotImplementedException("Unknown texture type"); } header.MipCount = reader.ReadByte(); // 8 header.PixelFormat = (BasePixelFormat)reader.ReadByte(); // 9 header.Unknown1 = reader.ReadByte(); // 10 header.Unknown2 = reader.ReadByte(); // 11 header.Unknown3 = reader.ReadByte(); // 12 header.Flags = reader.ReadByte(); // 13 header.Unknown4 = reader.ReadByte(); // 14 Something to do with mips. Autogen? header.Unknown5 = reader.ReadByte(); // 15 header.ResourceDataHash = BaseGGUUID.FromData(reader); // 16 texture.Header = header; // Raw pixel data handling uint containerSize = reader.ReadUInt32(); // Size of the remaining data being read long containerEndPosition = reader.BaseStream.Position + containerSize; texture.EmbeddedDataSize = reader.ReadUInt32(); // Size of pixel data in this core object entry. This value is never used. if (a - b > 0) only. uint streamedDataSize = reader.ReadUInt32(); // Size of pixel data in external file. This value is never used. if (a > 0) only. texture.StreamedMipCount = reader.ReadUInt32(); // Number of mipmaps in external file if (gameType == GameType.DS) { texture.DeathStrandingUnknown = reader.ReadUInt64(); } if (streamedDataSize > 0) { texture.StreamHandle = BaseStreamHandle.FromData(reader, gameType); } // TODO: Something is wrong here. EmbeddedDataSize doesn't always match the actual length of the byte array. Why? Does it depend on header flags? if (texture.EmbeddedDataSize > 0) { texture.EmbeddedTextureData = reader.ReadBytesStrict((uint)(containerEndPosition - reader.BaseStream.Position)); } return(texture); }