public override Texture2DContent Process(List <byte[]> input, ContentProcessorContext context) { for (int p = 0; p < input.Count; ++p) { if (input[p].Length != Height * Width * sizeof(float) * 3 / (1 << (2 * p))) { throw new InvalidContentException("The number of bytes in one or more of the images does not correlate with the product of the Height and Width properties."); } } MipmapChain imageChain = new MipmapChain(); int mip = 0; for (; mip < input.Count; ++mip) { byte[] paddedBytes = new byte[input[mip].Length / 3 * 4]; int srcIndex = 0; int destIndex = 0; while (srcIndex < input[mip].Length) { paddedBytes[destIndex++] = input[mip][srcIndex++]; if (srcIndex % 12 == 0) { for (int x = 0; x < 4; ++x) { paddedBytes[destIndex++] = 0; } } } int mipReduction = 1 << mip; BitmapContent image = new PixelBitmapContent <Vector4>(Width / mipReduction, Height / mipReduction); image.SetPixelData(paddedBytes); imageChain.Add(image); } // Check to see if this is a partial mipmap chain: if (imageChain.Count > 1) { // Just fill the rest of the chain with anything to satisfy the validator that the chain is complete. while ((Math.Max(Height, Width) >> (mip - 1)) > 1) { int mipReduction = 1 << mip; int mipHeight = Math.Max(Height / mipReduction, 1); int mipWidth = Math.Max(Width / mipReduction, 1); byte[] bytes = new byte[mipHeight * mipWidth * sizeof(float) * 4]; BitmapContent image = new PixelBitmapContent <Vector4>(mipWidth, mipHeight); image.SetPixelData(bytes); imageChain.Add(image); ++mip; } } Texture2DContent outputTC = new Texture2DContent(); outputTC.Mipmaps = imageChain; return(outputTC); }
public override TextureCubeContent Process(TextureCubeContent input, ContentProcessorContext context) { // System.Diagnostics.Debugger.Launch(); TextureCubeContent tc = new TextureCubeContent(); tc.Name = input.Name; tc.Identity = input.Identity; int i = 0; foreach (var item in input.Faces) { PixelBitmapContent <Color> bmpInput = (PixelBitmapContent <Color>)item[0]; // Create Intermediate Content Texture2DContent texMipMap = new Texture2DContent(); // Add decoded Vector4 texMipMap.Mipmaps.Add(Decode2(bmpInput)); // Generate Mip Maps texMipMap.GenerateMipmaps(true); MipmapChain mc = new MipmapChain(); // Convert each bitmap to Gamma Encoded SurfaceFormat.Color for (int mi = 0; mi < texMipMap.Mipmaps.Count; mi++) { // Get Mip Map PixelBitmapContent <Rgba1010102> bmpMipMap = (PixelBitmapContent <Rgba1010102>)texMipMap.Mipmaps[mi]; if (EncodeAfter) { PixelBitmapContent <Rgba1010102> bmpColor = Encode2(bmpMipMap); mc.Add(bmpColor); } else { mc.Add(bmpMipMap); } } tc.Faces[i++] = mc; } return(tc); }
internal static TextureContent Import(string filename, ContentImporterContext context) { var identity = new ContentIdentity(filename); TextureContent output = null; using (var fileStream = new FileStream(filename, FileMode.Open, FileAccess.Read)) using (var reader = new BinaryReader(fileStream)) { // Signature ("DDS ") if (reader.ReadByte() != 0x44 || reader.ReadByte() != 0x44 || reader.ReadByte() != 0x53 || reader.ReadByte() != 0x20) { throw new ContentLoadException("Invalid file signature"); } var header = new DdsHeader { // Read DDS_HEADER dwSize = reader.ReadUInt32() }; if (header.dwSize != 124) { throw new ContentLoadException("Invalid DDS_HEADER dwSize value"); } header.dwFlags = (Ddsd)reader.ReadUInt32(); header.dwHeight = reader.ReadUInt32(); header.dwWidth = reader.ReadUInt32(); header.dwPitchOrLinearSize = reader.ReadUInt32(); header.dwDepth = reader.ReadUInt32(); header.dwMipMapCount = reader.ReadUInt32(); // The next 11 DWORDs are reserved and unused for (int i = 0; i < 11; ++i) { reader.ReadUInt32(); } // Read DDS_PIXELFORMAT header.ddspf.dwSize = reader.ReadUInt32(); if (header.ddspf.dwSize != 32) { throw new ContentLoadException("Invalid DDS_PIXELFORMAT dwSize value"); } header.ddspf.dwFlags = (Ddpf)reader.ReadUInt32(); header.ddspf.dwFourCC = (FourCC)reader.ReadUInt32(); header.ddspf.dwRgbBitCount = reader.ReadUInt32(); header.ddspf.dwRBitMask = reader.ReadUInt32(); header.ddspf.dwGBitMask = reader.ReadUInt32(); header.ddspf.dwBBitMask = reader.ReadUInt32(); header.ddspf.dwABitMask = reader.ReadUInt32(); // Continue reading DDS_HEADER header.dwCaps = (DdsCaps)reader.ReadUInt32(); header.dwCaps2 = (DdsCaps2)reader.ReadUInt32(); reader.ReadUInt32(); // dwCaps3 unused reader.ReadUInt32(); // dwCaps4 unused reader.ReadUInt32(); // dwReserved2 unused // Check for the existence of the DDS_HEADER_DXT10 struct next if (header.ddspf.dwFlags == Ddpf.FourCC && header.ddspf.dwFourCC == FourCC.Dx10) { throw new ContentLoadException("Unsupported DDS_HEADER_DXT10 struct found"); } int faceCount = 1; int mipMapCount = (int)(header.dwCaps.HasFlag(DdsCaps.MipMap) ? header.dwMipMapCount : 1); if (header.dwCaps2.HasFlag(DdsCaps2.Cubemap)) { if (!header.dwCaps2.HasFlag(DdsCaps2.CubemapAllFaces)) { throw new ContentLoadException("Incomplete cubemap in DDS file"); } faceCount = 6; output = new TextureCubeContent() { Identity = identity }; } else { output = new Texture2DContent() { Identity = identity }; } var format = GetSurfaceFormat(ref header.ddspf, out bool rbSwap); for (int f = 0; f < faceCount; ++f) { int w = (int)header.dwWidth; int h = (int)header.dwHeight; var mipMaps = new MipmapChain(); for (int m = 0; m < mipMapCount; ++m) { var content = CreateBitmapContent(format, w, h); var byteCount = GetBitmapSize(format, w, h); // A 24-bit format is slightly different if (header.ddspf.dwRgbBitCount == 24) { byteCount = 3 * w * h; } var bytes = reader.ReadBytes(byteCount); if (rbSwap) { switch (format) { case SurfaceFormat.Bgr565: ByteSwapBGR565(bytes); break; case SurfaceFormat.Bgra4444: ByteSwapBGRA4444(bytes); break; case SurfaceFormat.Bgra5551: ByteSwapBGRA5551(bytes); break; case SurfaceFormat.Rgba32: if (header.ddspf.dwRgbBitCount == 32) { ByteSwapRGBX(bytes); } else if (header.ddspf.dwRgbBitCount == 24) { ByteSwapRGB(bytes); } break; } } if ((format == SurfaceFormat.Rgba32) && header.ddspf.dwFlags.HasFlag(Ddpf.Rgb) && !header.ddspf.dwFlags.HasFlag(Ddpf.AlphaPixels)) { // Fill or add alpha with opaque if (header.ddspf.dwRgbBitCount == 32) { ByteFillAlpha(bytes); } else if (header.ddspf.dwRgbBitCount == 24) { ByteExpandAlpha(ref bytes); } } content.SetPixelData(bytes); mipMaps.Add(content); w = Math.Max(1, w / 2); h = Math.Max(1, h / 2); } output.Faces[f] = mipMaps; } } return(output); }
static internal TextureContent Import(string filename, ContentImporterContext context) { var identity = new ContentIdentity(filename); TextureContent output = null; using (var reader = new BinaryReader(new FileStream(filename, FileMode.Open, FileAccess.Read))) { // Read signature ("DDS ") var valid = reader.ReadByte() == 0x44; valid = valid && reader.ReadByte() == 0x44; valid = valid && reader.ReadByte() == 0x53; valid = valid && reader.ReadByte() == 0x20; if (!valid) { throw new ContentLoadException("Invalid file signature"); } var header = new DdsHeader(); // Read DDS_HEADER header.dwSize = reader.ReadUInt32(); if (header.dwSize != 124) { throw new ContentLoadException("Invalid DDS_HEADER dwSize value"); } header.dwFlags = (Ddsd)reader.ReadUInt32(); header.dwHeight = reader.ReadUInt32(); header.dwWidth = reader.ReadUInt32(); header.dwPitchOrLinearSize = reader.ReadUInt32(); header.dwDepth = reader.ReadUInt32(); header.dwMipMapCount = reader.ReadUInt32(); // The next 11 DWORDs are reserved and unused for (int i = 0; i < 11; ++i) { reader.ReadUInt32(); } // Read DDS_PIXELFORMAT header.ddspf.dwSize = reader.ReadUInt32(); if (header.ddspf.dwSize != 32) { throw new ContentLoadException("Invalid DDS_PIXELFORMAT dwSize value"); } header.ddspf.dwFlags = (Ddpf)reader.ReadUInt32(); header.ddspf.dwFourCC = (FourCC)reader.ReadUInt32(); header.ddspf.dwRgbBitCount = reader.ReadUInt32(); header.ddspf.dwRBitMask = reader.ReadUInt32(); header.ddspf.dwGBitMask = reader.ReadUInt32(); header.ddspf.dwBBitMask = reader.ReadUInt32(); header.ddspf.dwABitMask = reader.ReadUInt32(); // Continue reading DDS_HEADER header.dwCaps = (DdsCaps)reader.ReadUInt32(); header.dwCaps2 = (DdsCaps2)reader.ReadUInt32(); // dwCaps3 unused reader.ReadUInt32(); // dwCaps4 unused reader.ReadUInt32(); // dwReserved2 unused reader.ReadUInt32(); // Check for the existence of the DDS_HEADER_DXT10 struct next if (header.ddspf.dwFlags == Ddpf.FourCC && header.ddspf.dwFourCC == FourCC.Dx10) { throw new ContentLoadException("Unsupported DDS_HEADER_DXT10 struct found"); } int faceCount = 1; int mipMapCount = (int)(header.dwCaps.HasFlag(DdsCaps.MipMap) ? header.dwMipMapCount : 1); if (header.dwCaps.HasFlag(DdsCaps.Complex)) { if (header.dwCaps2.HasFlag(DdsCaps2.Cubemap)) { if (!header.dwCaps2.HasFlag(DdsCaps2.CubemapAllFaces)) { throw new ContentLoadException("Incomplete cubemap in DDS file"); } faceCount = 6; output = new TextureCubeContent() { Identity = identity }; } else { output = new Texture2DContent() { Identity = identity }; } } else { output = new Texture2DContent() { Identity = identity }; } bool rbSwap; var format = GetSurfaceFormat(ref header.ddspf, out rbSwap); for (int f = 0; f < faceCount; ++f) { var w = (int)header.dwWidth; var h = (int)header.dwHeight; var mipMaps = new MipmapChain(); for (int m = 0; m < mipMapCount; ++m) { var content = CreateBitmapContent(format, w, h); var byteCount = GetBitmapSize(format, w, h); var bytes = reader.ReadBytes(byteCount); content.SetPixelData(bytes); mipMaps.Add(content); w = MathHelper.Max(1, w / 2); h = MathHelper.Max(1, h / 2); } output.Faces[f] = mipMaps; } } return(output); }
static internal TextureContent Import(string filename, ContentImporterContext context) { var identity = new ContentIdentity(filename); TextureContent output = null; using (var reader = new BinaryReader(new FileStream(filename, FileMode.Open, FileAccess.Read))) { // Read signature ("DDS ") var valid = reader.ReadByte() == 0x44; valid = valid && reader.ReadByte() == 0x44; valid = valid && reader.ReadByte() == 0x53; valid = valid && reader.ReadByte() == 0x20; if (!valid) throw new ContentLoadException("Invalid file signature"); var header = new DdsHeader(); // Read DDS_HEADER header.dwSize = reader.ReadUInt32(); if (header.dwSize != 124) throw new ContentLoadException("Invalid DDS_HEADER dwSize value"); header.dwFlags = (Ddsd)reader.ReadUInt32(); header.dwHeight = reader.ReadUInt32(); header.dwWidth = reader.ReadUInt32(); header.dwPitchOrLinearSize = reader.ReadUInt32(); header.dwDepth = reader.ReadUInt32(); header.dwMipMapCount = reader.ReadUInt32(); // The next 11 DWORDs are reserved and unused for (int i = 0; i < 11; ++i) reader.ReadUInt32(); // Read DDS_PIXELFORMAT header.ddspf.dwSize = reader.ReadUInt32(); if (header.ddspf.dwSize != 32) throw new ContentLoadException("Invalid DDS_PIXELFORMAT dwSize value"); header.ddspf.dwFlags = (Ddpf)reader.ReadUInt32(); header.ddspf.dwFourCC = (FourCC)reader.ReadUInt32(); header.ddspf.dwRgbBitCount = reader.ReadUInt32(); header.ddspf.dwRBitMask = reader.ReadUInt32(); header.ddspf.dwGBitMask = reader.ReadUInt32(); header.ddspf.dwBBitMask = reader.ReadUInt32(); header.ddspf.dwABitMask = reader.ReadUInt32(); // Continue reading DDS_HEADER header.dwCaps = (DdsCaps)reader.ReadUInt32(); header.dwCaps2 = (DdsCaps2)reader.ReadUInt32(); // dwCaps3 unused reader.ReadUInt32(); // dwCaps4 unused reader.ReadUInt32(); // dwReserved2 unused reader.ReadUInt32(); // Check for the existence of the DDS_HEADER_DXT10 struct next if (header.ddspf.dwFlags == Ddpf.FourCC && header.ddspf.dwFourCC == FourCC.Dx10) { throw new ContentLoadException("Unsupported DDS_HEADER_DXT10 struct found"); } int faceCount = 1; int mipMapCount = (int)(header.dwCaps.HasFlag(DdsCaps.MipMap) ? header.dwMipMapCount : 1); if (header.dwCaps.HasFlag(DdsCaps.Complex)) { if (header.dwCaps2.HasFlag(DdsCaps2.Cubemap)) { if (!header.dwCaps2.HasFlag(DdsCaps2.CubemapAllFaces)) throw new ContentLoadException("Incomplete cubemap in DDS file"); faceCount = 6; output = new TextureCubeContent() { Identity = identity }; } else { output = new Texture2DContent() { Identity = identity }; } } else { output = new Texture2DContent() { Identity = identity }; } bool rbSwap; var format = GetSurfaceFormat(ref header.ddspf, out rbSwap); for (int f = 0; f < faceCount; ++f) { var w = (int)header.dwWidth; var h = (int)header.dwHeight; var mipMaps = new MipmapChain(); for (int m = 0; m < mipMapCount; ++m) { var content = CreateBitmapContent(format, w, h); var byteCount = GetBitmapSize(format, w, h); var bytes = reader.ReadBytes(byteCount); content.SetPixelData(bytes); mipMaps.Add(content); w = MathHelper.Max(1, w / 2); h = MathHelper.Max(1, h / 2); } output.Faces[f] = mipMaps; } } return output; }