private byte[][] ddsFile_CreateBuffer(DdsFile ddsFile, out HaloBitmap.BitmapFormat format, ref int lodLevels, out bool linear, out bool swizzle, out bool deleteLods) { //Prepare format = HaloBitmap.BitmapFormat.Null; deleteLods = true; swizzle = false; linear = false; //Get Format if (ddsFile.PixelFormatFlags.HasFlag(DirectDrawPixelFormatFlags.FourCC)) //Check for FourCC flag... { switch (ddsFile.FourCC) //Check FourCC string { case "DXT1": format = HaloBitmap.BitmapFormat.Dxt1; break; case "DXT2": case "DXT3": format = HaloBitmap.BitmapFormat.Dxt3; break; case "DXT4": case "DXT5": format = HaloBitmap.BitmapFormat.Dxt5; break; case "ATI2": format = HaloBitmap.BitmapFormat.P8Bump; break; } switch (ddsFile.DwordFourCC) //Check FourCC int { case 116: format = HaloBitmap.BitmapFormat.Argbfp32; break; } } else { if (ddsFile.PixelFormatFlags.HasFlag(DirectDrawPixelFormatFlags.Argb)) //ARGB { switch (ddsFile.RgbBitCount) { case 16: //16bpp if (ddsFile.AlphaBitmask == 0x8000) { format = HaloBitmap.BitmapFormat.A1r5g5b5; //A1R5G5B5 } else { format = HaloBitmap.BitmapFormat.A4r4g4b4; //A4R4G4B4 } break; case 32: format = HaloBitmap.BitmapFormat.A8r8g8b8; break; //A8R8G8B8 } } else if (ddsFile.PixelFormatFlags.HasFlag(DirectDrawPixelFormatFlags.Rgb)) //RGB { switch (ddsFile.RgbBitCount) { case 16: format = HaloBitmap.BitmapFormat.R5g6b5; break; //R5G6B5 case 32: format = HaloBitmap.BitmapFormat.X8r8g8b8; break; //X8R8G8B8 } } else if (ddsFile.PixelFormatFlags.HasFlag(DirectDrawPixelFormatFlags.AlphaLuminance)) //AL { switch (ddsFile.RgbBitCount) { case 16: format = HaloBitmap.BitmapFormat.A8y8; break; //A8L8 } } else if (ddsFile.PixelFormatFlags.HasFlag(DirectDrawPixelFormatFlags.Luminance)) //L { switch (ddsFile.RgbBitCount) { case 8: format = HaloBitmap.BitmapFormat.Y8; break; //L8 } } else if (ddsFile.PixelFormatFlags.HasFlag(DirectDrawPixelFormatFlags.Argb)) //A { switch (ddsFile.RgbBitCount) { case 8: format = HaloBitmap.BitmapFormat.A8; break; //A8 } } else if (ddsFile.PixelFormatFlags.HasFlag(DirectDrawPixelFormatFlags.VU)) //VU { switch (ddsFile.RgbBitCount) { case 16: format = HaloBitmap.BitmapFormat.V8u8; break; //V8U8 } } } //Check if (format == HaloBitmap.BitmapFormat.Null) { switch (ddsFile.RgbBitCount) { case 8: format = HaloBitmap.BitmapFormat.Y8; break; case 16: format = HaloBitmap.BitmapFormat.A8y8; break; case 32: format = HaloBitmap.BitmapFormat.A8r8g8b8; break; default: throw new FormatException("DirectDraw Surface texture format is not supported."); } } //Confirm using (TextureImportOptionsDialog texDlg = new TextureImportOptionsDialog()) { //Setup int mapCount = 1 + (int)ddsFile.MipmapCount; texDlg.OriginalHeight = (int)ddsFile.Height; texDlg.OriginalWidth = (int)ddsFile.Width; texDlg.MaxLodLevels = mapCount; texDlg.LodLevels = lodLevels; texDlg.Format = format; //Show if (texDlg.ShowDialog(this) == DialogResult.OK) { lodLevels = texDlg.LodLevels; format = texDlg.Format; deleteLods = texDlg.DeleteLods; swizzle = texDlg.Swizzle; } else { return(null); } } //Prepare buffers byte[][] buffers = new byte[lodLevels][]; //Get BPP uint bitsPerPixel = 0; if (ddsFile.DefinitionFlags.HasFlag(DirectDrawSurfaceDefinitionFlags.LinearSize)) { bitsPerPixel = ddsFile.PitchOrLinearSize * 8u / ddsFile.Width / ddsFile.Height; } else { bitsPerPixel = ddsFile.RgbBitCount; } //Get Data Length long length = 0; uint mipWidth = ddsFile.Width, mipHeight = ddsFile.Height; for (int j = 0; j <= ddsFile.MipmapCount; j++) { length += mipWidth * mipHeight * bitsPerPixel / 8; mipWidth /= 2; mipHeight /= 2; } //Get Linear? if (ddsFile.RgbBitCount > 0) { linear = !swizzle; } //Get Data Lengths uint width = ddsFile.Width, height = ddsFile.Height; int position = 0; for (int i = 0; i < lodLevels; i++) { //Prepare int lodLength = 0; mipWidth = width; mipHeight = height; //Loop for (int j = i; j <= ddsFile.MipmapCount; j++) { lodLength += (int)(mipWidth * mipHeight * bitsPerPixel / 8); mipWidth /= 2; mipHeight /= 2; } //Prepare int mipPosition = 0; buffers[i] = new byte[lodLength]; mipWidth = width; mipHeight = height; for (int j = i; j <= ddsFile.MipmapCount; j++) { //Get Mip Data byte[] data = new byte[mipWidth * mipHeight * bitsPerPixel / 8]; Array.Copy(ddsFile.Data, mipPosition + position, data, 0, data.Length); //Swizzle? if (swizzle) { data = Swizzler.Swizzle(data, (int)mipWidth, (int)mipHeight, 1, (int)bitsPerPixel, !swizzle); } //Copy Array.Copy(data, 0, buffers[i], mipPosition, data.Length); //Increment mipPosition += (int)(mipWidth * mipHeight * bitsPerPixel / 8); mipWidth /= 2; mipHeight /= 2; } //Increment position += (int)(width * height * bitsPerPixel / 8); //Get next LOD width /= 2; height /= 2; } //Return return(buffers); }
private byte[] image_CreateBuffer(Image image, out bool linear, out bool swizzle, out bool deleteLods) { //Prepare linear = false; swizzle = false; deleteLods = true; byte[] buffer = new byte[image.Width * image.Height * 4]; //Get Color Data Color pixel = Color.Black; using (Bitmap bitmap = new Bitmap(image)) for (int y = 0; y < bitmap.Height; y++) { for (int x = 0; x < bitmap.Width; x++) { //Get Pixel pixel = bitmap.GetPixel(x, y); int a = y * bitmap.Width + x; //Copy into buffer buffer[a * 4] = pixel.B; buffer[a * 4 + 1] = pixel.G; buffer[a * 4 + 2] = pixel.R; buffer[a * 4 + 3] = pixel.A; } } //Confirm using (TextureImportOptionsDialog texDlg = new TextureImportOptionsDialog()) { //Setup texDlg.OriginalHeight = image.Height; texDlg.OriginalWidth = image.Width; texDlg.MaxLodLevels = 1; texDlg.LodLevels = 1; texDlg.Format = HaloBitmap.BitmapFormat.A8r8g8b8; //Show if (texDlg.ShowDialog(this) == DialogResult.OK) { deleteLods = texDlg.DeleteLods; swizzle = texDlg.Swizzle; } else { return(null); } } //Get Linear linear = !swizzle; //Check if (swizzle) { buffer = Swizzler.Swizzle(buffer, image.Width, image.Height, 1, 32, false); } //Return return(buffer); }