public static void Save(BinaryWriter bw, DDS dds) { Flags flags = (Flags.Caps | Flags.Height | Flags.Width | Flags.PixelFormat | Flags.MipMapCount); flags |= (dds.format == D3DFormat.A8R8G8B8 ? Flags.Pitch : Flags.LinearSize); bw.Write(new byte[] { 0x44, 0x44, 0x53, 0x20 }); // 'DDS ' bw.Write(124); bw.Write((int)flags); bw.Write(dds.Height); bw.Write(dds.Width); bw.Write((flags.HasFlag(Flags.Pitch) ? dds.width * 4 : dds.MipMaps[0].Data.Length)); bw.Write(dds.Depth); bw.Write(dds.MipMaps.Count); for (int i = 0; i < 11; i++) { bw.Write(0); } // PixelFormat bw.Write(32); switch (dds.Format) { case D3DFormat.DXT1: case D3DFormat.DXT3: case D3DFormat.DXT5: bw.Write(4); // fourCC length bw.Write(dds.Format.ToString().ToCharArray()); bw.Write(0); bw.Write(0); bw.Write(0); bw.Write(0); bw.Write(0); break; default: bw.Write(0); // fourCC length bw.Write(0); bw.Write(32); // RGB bit count bw.Write(255 << 16); // R mask bw.Write(255 << 8); // G mask bw.Write(255 << 0); // B mask bw.Write(255 << 24); // A mask break; } bw.Write((int)DDSCaps.DDSCAPS_TEXTURE); bw.Write(0); // Caps 2 bw.Write(0); // Caps 3 bw.Write(0); // Caps 4 bw.Write(0); // Reserved for (int i = 0; i < dds.mipMaps.Count; i++) { bw.Write(dds.mipMaps[i].Data); } }
public void ExtractTexture(FileStream fs, string path, int Flags) { DDS dds = new DDS(); int[] dimensionLookup = new int[] { 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096 }; int size = 0; int u = (Flags & 0x00F00000) >> 20; int v = (Flags & 0x0F000000) >> 24; int f = (Flags & 0x0000FF00) >> 8; switch (f) { case 12: // DXT1 size = (dimensionLookup[u] * dimensionLookup[v]) / 2; dds.Format = D3DFormat.DXT1; break; case 15: // DXT5 size = dimensionLookup[u] * dimensionLookup[v]; dds.Format = D3DFormat.DXT5; break; default: throw new NotImplementedException(string.Format("Unknown texture format: {0}", f)); } dds.Width = dimensionLookup[u]; dds.Height = dimensionLookup[v]; dds.MipMaps.Add(new Generics.MipMap { Width = dds.Width, Height = dds.Height, Data = new byte[size] }); fs.Read(dds.MipMaps[0].Data, 0, size); dds.Save(path); }
public static DDS Load(byte[] data) { DDS dds = new DDS(); using (MemoryStream ms = new MemoryStream(data)) using (BinaryReader br = new BinaryReader(ms)) { if (!IsDDS(br)) { return null; } dds.pixelFormat = new DDSPixelFormat(); br.ReadUInt32(); // header length dds.flags = (Flags)br.ReadUInt32(); dds.height = (int)br.ReadUInt32(); dds.width = (int)br.ReadUInt32(); dds.pitch = (int)br.ReadUInt32(); dds.depth = (int)br.ReadUInt32(); int mipCount = (int)br.ReadUInt32(); for (int i = 0; i < 11; i++) { br.ReadUInt32(); } br.ReadUInt32(); // pixel format length dds.pixelFormat.Flags = (PixelFormatFlags)br.ReadUInt32(); dds.pixelFormat.FourCC = (PixelFormatFourCC)br.ReadUInt32(); dds.pixelFormat.RGBBitCount = (int)br.ReadUInt32(); dds.pixelFormat.RBitMask = br.ReadUInt32(); dds.pixelFormat.GBitMask = br.ReadUInt32(); dds.pixelFormat.BBitMask = br.ReadUInt32(); dds.pixelFormat.ABitMask = br.ReadUInt32(); dds.caps = (DDSCaps)br.ReadUInt32(); dds.caps2 = (DDSCaps2)br.ReadUInt32(); br.ReadUInt32(); br.ReadUInt32(); br.ReadUInt32(); if (dds.pixelFormat.Flags.HasFlag(PixelFormatFlags.DDPF_FOURCC)) { dds.format = (D3DFormat)dds.pixelFormat.FourCC; } else if (dds.pixelFormat.Flags.HasFlag(PixelFormatFlags.DDPF_RGB) & dds.pixelFormat.Flags.HasFlag(PixelFormatFlags.DDPF_ALPHAPIXELS)) { dds.format = D3DFormat.A8R8G8B8; } for (int i = 0; i < Math.Max(1, mipCount); i++) { var mip = new MipMap { Width = dds.width >> i, Height = dds.height >> i }; switch (dds.format) { case D3DFormat.A8R8G8B8: mip.Data = br.ReadBytes(mip.Width * mip.Height * 4); break; case D3DFormat.DXT1: mip.Data = br.ReadBytes((((mip.Width + 3) / 4) * ((mip.Height + 3) / 4)) * 8); break; case D3DFormat.DXT3: case D3DFormat.DXT5: mip.Data = br.ReadBytes((((mip.Width + 3) / 4) * ((mip.Height + 3) / 4)) * 16); break; } dds.mipMaps.Add(mip); } } return dds; }
public static DDS Load(byte[] data) { DDS dds = new DDS(); using (MemoryStream ms = new MemoryStream(data)) using (BinaryReader br = new BinaryReader(ms)) { if (!IsDDS(br)) { return(null); } br.ReadUInt32(); // header length dds.Flags = (HeaderFlags)br.ReadUInt32(); dds.Height = (int)br.ReadUInt32(); dds.Width = (int)br.ReadUInt32(); dds.Pitch = (int)br.ReadUInt32(); dds.Depth = (int)br.ReadUInt32(); int mipCount = (int)br.ReadUInt32(); for (int i = 0; i < 11; i++) { br.ReadUInt32(); } br.ReadUInt32(); // pixel format length dds.PixelFormat = new DDSPixelFormat { Flags = (PixelFormatFlags)br.ReadUInt32(), FourCC = (PixelFormatFourCC)br.ReadUInt32(), RGBBitCount = (int)br.ReadUInt32(), RBitMask = br.ReadUInt32(), GBitMask = br.ReadUInt32(), BBitMask = br.ReadUInt32(), ABitMask = br.ReadUInt32() }; dds.Caps = (DDSCaps)br.ReadUInt32(); dds.Caps2 = (DDSCaps2)br.ReadUInt32(); br.ReadUInt32(); br.ReadUInt32(); br.ReadUInt32(); if (dds.PixelFormat.Flags.HasFlag(PixelFormatFlags.DDPF_FOURCC)) { dds.Format = (D3DFormat)dds.PixelFormat.FourCC; } else if (dds.PixelFormat.Flags.HasFlag(PixelFormatFlags.DDPF_RGB) & dds.PixelFormat.Flags.HasFlag(PixelFormatFlags.DDPF_ALPHAPIXELS)) { dds.Format = D3DFormat.A8R8G8B8; } for (int i = 0; i < Math.Max(1, mipCount); i++) { MipMap mip = new MipMap { Width = dds.Width >> i, Height = dds.Height >> i }; switch (dds.Format) { case D3DFormat.A8R8G8B8: mip.Data = br.ReadBytes(mip.Width * mip.Height * 4); break; case D3DFormat.DXT1: mip.Data = br.ReadBytes((((mip.Width + 3) / 4) * ((mip.Height + 3) / 4)) * 8); break; case D3DFormat.DXT3: case D3DFormat.DXT5: mip.Data = br.ReadBytes((((mip.Width + 3) / 4) * ((mip.Height + 3) / 4)) * 16); break; } dds.MipMaps.Add(mip); } } return(dds); }