コード例 #1
0
ファイル: HaloBitmap.cs プロジェクト: MikeMatt16/Abide
        /// <summary>
        /// Initializes a new <see cref="HaloBitmap"/> instance using the supplied object index entry.
        /// </summary>
        /// <param name="entry">The object index entry that contains the bitmap tag group data.</param>
        /// <exception cref="ArgumentNullException"><paramref name="entry"/> is null.</exception>
        /// <exception cref="ArgumentException"><paramref name="entry"/> is not a bitmap.</exception>
        public HaloBitmap(IndexEntry entry)
        {
            //Check
            if (entry == null)
            {
                throw new ArgumentNullException(nameof(entry));
            }
            else if (entry.Root != HaloTags.bitm)
            {
                throw new ArgumentException("Index entry is not bitmap.", nameof(entry));
            }

            //Setup
            this.entry = entry;
            tag        = new BitmapTag(entry);
            maps       = new Bitmap[tag.Bitmaps.Length][][];

            //Setup Property Accessors
            bitmaps = new BitmapProperties[tag.Bitmaps.Length];
            for (int i = 0; i < tag.Bitmaps.Length; i++)
            {
                bitmaps[i] = new BitmapProperties(this, i);
            }
            sequences = new SequenceProperties[tag.Sequences.Length];
            for (int i = 0; i < tag.Sequences.Length; i++)
            {
                sequences[i] = new SequenceProperties(this, i);
            }

            //Check
            if (tag == null)
            {
                return;
            }
            else if (tag.Bitmaps.Length == 0)
            {
                return;
            }

            //Loop through bitmaps
            for (int k = 0; k < tag.Bitmaps.Length; k++)
            {
                //Setup
                BitmapTagGroup.Bitmap bitmap = tag.Bitmaps[k];
                maps[k] = new Bitmap[6][];

                //Loop through LODs
                byte[] sourceData = null;
                for (int l = 0; l < 6; l++)
                {
                    //Get source data
                    if (bitmap.rawOffsets[l] != uint.MaxValue)
                    {
                        RawLocation rawLocation = (RawLocation)(bitmap.rawOffsets[l] & 0xC0000000);
                        if (rawLocation == RawLocation.Local)
                        {
                            sourceData = entry.Raws[RawSection.Bitmap][(int)bitmap.rawOffsets[l]].GetBuffer();
                        }
                        else
                        {
                            string filelocation = string.Empty;
                            int    rawOffset    = (int)(bitmap.rawOffsets[l] & (uint)RawLocation.LocalMask);
                            switch (rawLocation)
                            {
                            case RawLocation.Mainmenu:
                                filelocation = HaloSettings.MainmenuPath;
                                break;

                            case RawLocation.Shared:
                                filelocation = HaloSettings.SharedPath;
                                break;

                            case RawLocation.SinglePlayerShared:
                                filelocation = HaloSettings.SingleplayerSharedPath;
                                break;
                            }

                            //Check
                            if (File.Exists(filelocation))
                            {
                                using (FileStream fs = new FileStream(filelocation, FileMode.Open))
                                    using (BinaryReader mapReader = new BinaryReader(fs))
                                    {
                                        fs.Seek(rawOffset, SeekOrigin.Begin);
                                        sourceData = mapReader.ReadBytes(bitmap.rawLengths[l]);
                                    }
                            }
                        }
                    }

                    //Set
                    if (sourceData.Length == 0)
                    {
                        continue;
                    }

                    //Prepare
                    BitmapFlags  flags        = (BitmapFlags)bitmap.flags;
                    BitmapFormat format       = (BitmapFormat)bitmap.format;
                    PixelFormat  bitmapFormat = PixelFormat.Format32bppArgb;
                    int          sourceBits   = 32;
                    switch (format)
                    {
                    case BitmapFormat.A8:
                    case BitmapFormat.Y8:
                    case BitmapFormat.P8Bump:
                    case BitmapFormat.P8:
                    case BitmapFormat.Ay8: sourceBits = 8; break;

                    case BitmapFormat.A8y8:
                    case BitmapFormat.A1r5g5b5:
                    case BitmapFormat.A4r4g4b4:
                    case BitmapFormat.V8u8:
                    case BitmapFormat.G8b8:
                    case BitmapFormat.R5g6b5: sourceBits = 16; break;

                    case BitmapFormat.Dxt1: sourceBits = 4; break;

                    case BitmapFormat.Dxt5:
                    case BitmapFormat.Dxt3: sourceBits = 8; break;

                    case BitmapFormat.Argbfp32: sourceBits = 128; break;
                    }

                    //Handle
                    switch (format)
                    {
                    case BitmapFormat.R5g6b5: bitmapFormat = PixelFormat.Format16bppRgb565; break;

                    case BitmapFormat.A1r5g5b5: bitmapFormat = PixelFormat.Format16bppArgb1555; break;

                    case BitmapFormat.X8r8g8b8: bitmapFormat = PixelFormat.Format32bppRgb; break;

                    case BitmapFormat.P8Bump: bitmapFormat = PixelFormat.Format8bppIndexed; break;

                    case BitmapFormat.P8: bitmapFormat = PixelFormat.Format8bppIndexed; break;
                    }

                    //Prepare
                    int width = bitmap.width, height = bitmap.height;
                    if (flags.HasFlag(BitmapFlags.Linear))
                    {
                        width = (int)Math.Ceiling(width / 16f) * 16;
                    }

                    //Loop LOD
                    for (int i = 0; i < l; i++)
                    {
                        width  /= 2;
                        height /= 2;
                    }

                    //Prepare
                    int mapWidth = width, mapHeight = height, location = 0;
                    int mipmapCount = bitmap.mipmapCount;
                    maps[k][l] = new Bitmap[mipmapCount + 1];
                    Size   bitmapSize = Size.Empty;
                    byte[] mapData    = null;

                    //Loop
                    for (int i = 1; i <= mipmapCount + 1; i++)
                    {
                        //Prepare
                        int mapIndex = i - 1;
                        mapWidth = width; mapHeight = height;
                        for (int j = 1; j < i; j++)
                        {
                            mapWidth  /= 2;
                            mapHeight /= 2;
                        }

                        //Get Size
                        bitmapSize = new Size(mapWidth, mapHeight);

                        //Check
                        if (bitmapSize.Width == 0 || bitmapSize.Height == 0)
                        {
                            continue;
                        }

                        //Create Map
                        int mapStride = mapWidth * sourceBits / 8;
                        int mapSize   = mapStride * mapHeight;

                        //Ehh?
                        switch (format)
                        {
                        case BitmapFormat.Dxt1: mapSize = Math.Max(mapSize, 8); break;

                        case BitmapFormat.Dxt3:
                        case BitmapFormat.Dxt5: mapSize = Math.Max(mapSize, 16); break;

                        case BitmapFormat.P8:
                        case BitmapFormat.P8Bump: mapSize = Math.Max(mapSize, 16); break;

                        default: mapSize = Math.Max(mapSize, 1); break;
                        }

                        mapData = new byte[mapSize];
                        if (location + mapSize > sourceData.Length)
                        {
                            continue;
                        }
                        Array.Copy(sourceData, location, mapData, 0, mapSize);

                        //Deswizzle?
                        if ((flags & BitmapFlags.Swizzled) == BitmapFlags.Swizzled)
                        {
                            mapData = Swizzler.Swizzle(mapData, mapWidth, mapHeight, bitmap.depth, sourceBits, true);
                        }
                        if (mapData == null)
                        {
                            mapData = new byte[mapSize];
                        }

                        using (Bitmap map = new Bitmap(mapWidth, mapHeight, bitmapFormat))
                        {
                            unsafe
                            {
                                //Lock Bits
                                BitmapData data = map.LockBits(new Rectangle(0, 0, mapWidth, mapHeight), ImageLockMode.ReadWrite, bitmapFormat);

                                //Prepare Buffer
                                byte[] bitmapData = new byte[data.Stride * data.Height];
                                int    dataLength = Math.Min(bitmapData.Length, mapSize);

                                //Handle Format...
                                switch (format)
                                {
                                case BitmapFormat.A8:
                                    for (int x = 0; x < mapWidth * mapHeight; x++)
                                    {
                                        bitmapData[x * 4 + 0] = 255;
                                        bitmapData[x * 4 + 1] = 255;
                                        bitmapData[x * 4 + 2] = 255;
                                        bitmapData[x * 4 + 3] = mapData[x];
                                    }
                                    break;

                                case BitmapFormat.Y8:
                                    for (int x = 0; x < mapWidth * mapHeight; x++)
                                    {
                                        bitmapData[x * 4 + 0] = mapData[x];
                                        bitmapData[x * 4 + 1] = mapData[x];
                                        bitmapData[x * 4 + 2] = mapData[x];
                                        bitmapData[x * 4 + 3] = 255;
                                    }
                                    break;

                                case BitmapFormat.Ay8:
                                    for (int x = 0; x < mapWidth * mapHeight; x++)
                                    {
                                        bitmapData[x * 4 + 0] = mapData[x];
                                        bitmapData[x * 4 + 1] = mapData[x];
                                        bitmapData[x * 4 + 2] = mapData[x];
                                        bitmapData[x * 4 + 3] = mapData[x];
                                    }
                                    break;

                                case BitmapFormat.A8y8:
                                    for (int x = 0; x < mapWidth * mapHeight; x++)
                                    {
                                        bitmapData[x * 4 + 0] = mapData[x * 2];
                                        bitmapData[x * 4 + 1] = mapData[x * 2];
                                        bitmapData[x * 4 + 2] = mapData[x * 2];
                                        bitmapData[x * 4 + 3] = mapData[x * 2 + 1];
                                    }
                                    break;

                                case BitmapFormat.A4r4g4b4:
                                    for (int x = 0; x < mapWidth * mapHeight; x++)
                                    {
                                        bitmapData[x * 4 + 0] = (byte)(mapData[x * 2 + 0] & 0xF0);
                                        bitmapData[x * 4 + 1] = (byte)(mapData[x * 2 + 0] & 0x0F);
                                        bitmapData[x * 4 + 2] = (byte)(mapData[x * 2 + 1] & 0xF0);
                                        bitmapData[x * 4 + 3] = (byte)(mapData[x * 2 + 1] & 0x0F);
                                    }
                                    break;

                                case BitmapFormat.P8Bump:
                                case BitmapFormat.P8: Array.Copy(mapData, 0, bitmapData, 0, dataLength); break;

                                case BitmapFormat.R5g6b5: Array.Copy(mapData, 0, bitmapData, 0, dataLength); break;

                                case BitmapFormat.A1r5g5b5: Array.Copy(mapData, 0, bitmapData, 0, dataLength); break;

                                case BitmapFormat.X8r8g8b8: Array.Copy(mapData, 0, bitmapData, 0, dataLength); break;

                                case BitmapFormat.A8r8g8b8: Array.Copy(mapData, 0, bitmapData, 0, dataLength); break;

                                case BitmapFormat.Dxt1:
                                    if (mapWidth >= 4 && mapHeight >= 4)
                                    {
                                        S3TC.DecompressDxt1(ref bitmapData, mapData, bitmapSize);
                                    }
                                    break;

                                case BitmapFormat.Dxt3:
                                    if (mapWidth >= 4 && mapHeight >= 4)
                                    {
                                        S3TC.DecompressDxt3(ref bitmapData, mapData, bitmapSize);
                                    }
                                    break;

                                case BitmapFormat.Dxt5:
                                    if (mapWidth >= 4 && mapHeight >= 4)
                                    {
                                        S3TC.DecompressDxt5(ref bitmapData, mapData, bitmapSize);
                                    }
                                    break;

                                case BitmapFormat.Argbfp32:
                                    for (int x = 0; x < mapWidth * mapHeight; x++)
                                    {
                                        bitmapData[x * 4 + 0] = (byte)Math.Min((BitConverter.ToSingle(mapData, x * 16 + 8) * 255f), 255f);
                                        bitmapData[x * 4 + 1] = (byte)Math.Min((BitConverter.ToSingle(mapData, x * 16 + 4) * 255f), 255f);
                                        bitmapData[x * 4 + 2] = (byte)Math.Min((BitConverter.ToSingle(mapData, x * 16) * 255f), 255f);
                                        bitmapData[x * 4 + 3] = (byte)Math.Min((BitConverter.ToSingle(mapData, x * 16 + 12) * 255f), 255f);
                                    }
                                    break;

                                case BitmapFormat.Rgbfp32: break;

                                case BitmapFormat.Rgbfp16: break;

                                case BitmapFormat.V8u8:
                                    for (int x = 0; x < mapWidth * mapHeight; x++)
                                    {
                                        bitmapData[x * 4 + 0] = 255;
                                        bitmapData[x * 4 + 1] = (byte)(127 + (sbyte)mapData[x * 2 + 1]);
                                        bitmapData[x * 4 + 2] = (byte)(127 + (sbyte)mapData[x * 2]);
                                        bitmapData[x * 4 + 3] = 255;
                                    }
                                    break;

                                case BitmapFormat.G8b8: break;
                                }

                                //Copy
                                Marshal.Copy(bitmapData, 0, data.Scan0, bitmapData.Length);
                                map.UnlockBits(data);

                                //Setup Palettes
                                if (format == BitmapFormat.P8Bump)
                                {
                                    map.SetNormalMapPalette();
                                }
                                else if (format == BitmapFormat.P8)
                                {
                                    map.SetGrayscalePalette();
                                }

                                //Set
                                location += mapSize;
                            }

                            //Draw into cropped image
                            maps[k][l][mapIndex] = new Bitmap(bitmap.width, bitmap.height, bitmapFormat);
                            using (Graphics g = Graphics.FromImage(maps[k][l][mapIndex])) g.DrawImage(map, Point.Empty);
                        }
                    }
                }
            }
        }
コード例 #2
0
        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);
        }
コード例 #3
0
 public LandTextureMap(short[,] textureIndexMapping, bool swizzled)
 {
     this.textureIndexMapping = Validation.ValidateSquare(textureIndexMapping, TEXTURE_MAPPING_SIDE_LENGTH, "textureIndexMapping", "Texture Index Mapping");
     Swizzled = swizzled;
     swizzler = new Swizzler(textureIndexMapping);
 }
コード例 #4
0
        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);
        }
コード例 #5
0
        private void exportToolStripButton_Click(object sender, EventArgs e)
        {
            //Prepare
            string filename = string.Empty;
            bool   save     = false;

            //Get Filename
            string[] parts = this.bitmap.Entry.Filename.Split(new char[] { '\\' }, StringSplitOptions.RemoveEmptyEntries);
            if (parts.Length > 0)
            {
                filename = parts[parts.Length - 1];
            }

            //Initialize
            using (SaveFileDialog saveDlg = new SaveFileDialog())
            {
                //Setup
                saveDlg.Filter   = "DirectDraw Surface Files (*.dds)|*.dds";
                saveDlg.Title    = "Save texture as...";
                saveDlg.FileName = filename;
                if (saveDlg.ShowDialog() == DialogResult.OK)
                {
                    filename = saveDlg.FileName;
                    save     = true;
                }
            }

            //Prepare
            HaloBitmap.BitmapProperties bitmap = null;
            int bitmapIndex = (int)bitmapUpDown.Value;

            //Check
            if (save)
            {
                //Get Bitmap
                bitmap = this.bitmap.Bitmaps[bitmapIndex];
                uint width = bitmap.Width, height = bitmap.Height, depth = bitmap.Depth;
                bool swizzled = (bitmap.Flags & HaloBitmap.BitmapFlags.Swizzled) == HaloBitmap.BitmapFlags.Swizzled;
                if ((bitmap.Flags & HaloBitmap.BitmapFlags.PowTwoDimensions) == 0 && bitmap.MipmapCount == 0)
                {
                    width = width + (16 - (width % 16) == 16 ? 0 : 16 - (width % 16));  //Pad width to 16 for some ungodly reason
                }
                //Setup DDS file
                DdsFile file = new DdsFile();
                file.Width             = width;
                file.Height            = height;
                file.MipmapCount       = bitmap.MipmapCount;
                file.DefinitionFlags  |= DirectDrawSurfaceDefinitionFlags.PixelFormat | DirectDrawSurfaceDefinitionFlags.Width | DirectDrawSurfaceDefinitionFlags.Height | DirectDrawSurfaceDefinitionFlags.Caps;
                file.Caps             |= DirectDrawCaps.Texture;
                file.PitchOrLinearSize = (uint)bitmap_GetLength(bitmap.Format, bitmap.Width, bitmap.Height);
                file.DefinitionFlags  |= DirectDrawSurfaceDefinitionFlags.LinearSize;
                if (file.MipmapCount > 0)
                {
                    file.Caps |= DirectDrawCaps.Mipmap | DirectDrawCaps.Complex; file.DefinitionFlags |= DirectDrawSurfaceDefinitionFlags.MipmapCount;
                }

                //Setup Pixel Format
                switch (bitmap.Format)
                {
                case HaloBitmap.BitmapFormat.Dxt1: file.RgbBitCount = 0; file.FourCC = "DXT1"; file.PixelFormatFlags |= DirectDrawPixelFormatFlags.FourCC; break;

                case HaloBitmap.BitmapFormat.Dxt3: file.RgbBitCount = 0; file.FourCC = "DXT3"; file.PixelFormatFlags |= DirectDrawPixelFormatFlags.FourCC; break;

                case HaloBitmap.BitmapFormat.Dxt5: file.RgbBitCount = 0; file.FourCC = "DXT5"; file.PixelFormatFlags |= DirectDrawPixelFormatFlags.FourCC; break;

                case HaloBitmap.BitmapFormat.V8u8: file.RgbBitCount = 16; file.PixelFormatFlags = DirectDrawPixelFormatFlags.VU; break;

                default: file.RgbBitCount = (uint)bitmapFormat_GetBitCount(bitmap.Format); break;
                }
                uint aMask = 0, rMask = 0, gMask = 0, bMask = 0;
                bitmapFormat_GetBitMask(bitmap.Format, out aMask, out rMask, out bMask, out gMask);
                file.AlphaBitmask = aMask; file.RedBitmask = rMask; file.GreenBitmask = gMask; file.BlueBitmask = bMask;

                //Setup Bits
                switch (bitmap.Format)
                {
                case HaloBitmap.BitmapFormat.A8: file.PixelFormatFlags |= DirectDrawPixelFormatFlags.AlphaPixels; break;

                case HaloBitmap.BitmapFormat.Y8: file.PixelFormatFlags |= DirectDrawPixelFormatFlags.Luminance; break;

                case HaloBitmap.BitmapFormat.Ay8: file.PixelFormatFlags |= DirectDrawPixelFormatFlags.AlphaPixels; break;

                case HaloBitmap.BitmapFormat.G8b8: file.PixelFormatFlags |= DirectDrawPixelFormatFlags.AlphaLuminance; break;

                case HaloBitmap.BitmapFormat.A8y8: file.PixelFormatFlags |= DirectDrawPixelFormatFlags.AlphaLuminance; break;

                case HaloBitmap.BitmapFormat.R5g6b5: file.PixelFormatFlags |= DirectDrawPixelFormatFlags.Rgb; break;

                case HaloBitmap.BitmapFormat.A4r4g4b4: file.PixelFormatFlags |= DirectDrawPixelFormatFlags.Argb; break;

                case HaloBitmap.BitmapFormat.X8r8g8b8: file.PixelFormatFlags |= DirectDrawPixelFormatFlags.Rgb; break;

                case HaloBitmap.BitmapFormat.A8r8g8b8: file.PixelFormatFlags |= DirectDrawPixelFormatFlags.Argb; break;
                }

                //Prepare File Data
                int mapWidth = (int)width, mapHeight = (int)height;
                file.Data = new byte[bitmap.RawLengths[0]];
                using (MemoryStream ds = new MemoryStream(file.Data))
                    using (MemoryStream ms = new MemoryStream(bitmap_LoadData(bitmapIndex, 0)))
                        using (BinaryWriter writer = new BinaryWriter(ds))
                            using (BinaryReader reader = new BinaryReader(ms))
                                for (int i = 0; i <= bitmap.MipmapCount; i++)
                                {
                                    byte[] data = reader.ReadBytes(bitmap_GetLength(bitmap.Format, mapWidth, mapHeight));
                                    if (data.Length > 0)
                                    {
                                        writer.Write(swizzled ? Swizzler.Swizzle(data, mapWidth, mapHeight, (int)depth, (int)file.RgbBitCount, swizzled) : data);
                                    }
                                    mapWidth /= 2; mapHeight /= 2;
                                }

                //Save
                file.Save(filename);
            }
        }
コード例 #6
0
        private void dumpTexturesToolStripButton_Click(object sender, EventArgs e)
        {
            //Check
            if (bitmap == null)
            {
                return;
            }

            //Prepare
            string directory = string.Empty;
            bool   ok        = false;

            //Initialize
            using (FolderBrowserDialog folderDlg = new FolderBrowserDialog())
            {
                //Setup
                folderDlg.Description = "Select directory to dump textures.";

                //Show
                if (folderDlg.ShowDialog() == DialogResult.OK)
                {
                    directory = folderDlg.SelectedPath;
                    ok        = true;
                }
            }

            //Check
            if (ok)
            {
                //Prepare
                HaloBitmap.BitmapProperties bitmap = null;
                string[] parts    = this.bitmap.Entry.Filename.Split(new char[] { '\\' }, StringSplitOptions.RemoveEmptyEntries);
                string   filename = Path.Combine(directory, $"{parts[parts.Length - 1]}_{{0}}.dds");

                //Loop
                for (int b = 0; b < this.bitmap.BitmapCount; b++)
                {
                    //Get Bitmap
                    bitmap = this.bitmap.Bitmaps[b];
                    uint width = bitmap.Width, height = bitmap.Height, depth = bitmap.Depth;
                    bool swizzled = (bitmap.Flags & HaloBitmap.BitmapFlags.Swizzled) == HaloBitmap.BitmapFlags.Swizzled;
                    if ((bitmap.Flags & HaloBitmap.BitmapFlags.PowTwoDimensions) == 0 && bitmap.MipmapCount == 0)
                    {
                        width = (uint)Math.Ceiling(width / 16f) * 16;    //Pad width to 16 for some ungodly reason
                    }
                    //Setup DDS file
                    DdsFile file = new DdsFile();
                    file.Width             = width;
                    file.Height            = height;
                    file.MipmapCount       = bitmap.MipmapCount;
                    file.DefinitionFlags  |= DirectDrawSurfaceDefinitionFlags.PixelFormat | DirectDrawSurfaceDefinitionFlags.Width | DirectDrawSurfaceDefinitionFlags.Height | DirectDrawSurfaceDefinitionFlags.Caps;
                    file.Caps             |= DirectDrawCaps.Texture;
                    file.PitchOrLinearSize = (uint)bitmap_GetLength(bitmap.Format, bitmap.Width, bitmap.Height);
                    file.DefinitionFlags  |= DirectDrawSurfaceDefinitionFlags.LinearSize;
                    if (file.MipmapCount > 0)
                    {
                        file.Caps |= DirectDrawCaps.Mipmap | DirectDrawCaps.Complex; file.DefinitionFlags |= DirectDrawSurfaceDefinitionFlags.MipmapCount;
                    }

                    //Setup Pixel Format
                    switch (bitmap.Format)
                    {
                    case HaloBitmap.BitmapFormat.Dxt1: file.RgbBitCount = 0; file.FourCC = "DXT1"; file.PixelFormatFlags |= DirectDrawPixelFormatFlags.FourCC; break;

                    case HaloBitmap.BitmapFormat.Dxt3: file.RgbBitCount = 0; file.FourCC = "DXT3"; file.PixelFormatFlags |= DirectDrawPixelFormatFlags.FourCC; break;

                    case HaloBitmap.BitmapFormat.Dxt5: file.RgbBitCount = 0; file.FourCC = "DXT5"; file.PixelFormatFlags |= DirectDrawPixelFormatFlags.FourCC; break;

                    case HaloBitmap.BitmapFormat.V8u8: file.RgbBitCount = 16; file.PixelFormatFlags = DirectDrawPixelFormatFlags.VU; break;

                    default: file.RgbBitCount = (uint)bitmapFormat_GetBitCount(bitmap.Format); break;
                    }
                    uint aMask = 0, rMask = 0, gMask = 0, bMask = 0;
                    bitmapFormat_GetBitMask(bitmap.Format, out aMask, out rMask, out bMask, out gMask);
                    file.AlphaBitmask = aMask; file.RedBitmask = rMask; file.GreenBitmask = gMask; file.BlueBitmask = bMask;

                    //Setup Bits
                    switch (bitmap.Format)
                    {
                    case HaloBitmap.BitmapFormat.A8: file.PixelFormatFlags |= DirectDrawPixelFormatFlags.AlphaPixels; break;

                    case HaloBitmap.BitmapFormat.Y8: file.PixelFormatFlags |= DirectDrawPixelFormatFlags.Luminance; break;

                    case HaloBitmap.BitmapFormat.Ay8: file.PixelFormatFlags |= DirectDrawPixelFormatFlags.AlphaPixels; break;

                    case HaloBitmap.BitmapFormat.G8b8: file.PixelFormatFlags |= DirectDrawPixelFormatFlags.AlphaLuminance; break;

                    case HaloBitmap.BitmapFormat.A8y8: file.PixelFormatFlags |= DirectDrawPixelFormatFlags.AlphaLuminance; break;

                    case HaloBitmap.BitmapFormat.R5g6b5: file.PixelFormatFlags |= DirectDrawPixelFormatFlags.Rgb; break;

                    case HaloBitmap.BitmapFormat.A4r4g4b4: file.PixelFormatFlags |= DirectDrawPixelFormatFlags.Argb; break;

                    case HaloBitmap.BitmapFormat.X8r8g8b8: file.PixelFormatFlags |= DirectDrawPixelFormatFlags.Rgb; break;

                    case HaloBitmap.BitmapFormat.A8r8g8b8: file.PixelFormatFlags |= DirectDrawPixelFormatFlags.Argb; break;
                    }

                    //Prepare File Data
                    int mapWidth = (int)width, mapHeight = (int)height;
                    file.Data = new byte[bitmap.RawLengths[0]];
                    using (MemoryStream ds = new MemoryStream(file.Data))
                        using (MemoryStream ms = new MemoryStream(bitmap_LoadData(b, 0)))
                            using (BinaryWriter writer = new BinaryWriter(ds))
                                using (BinaryReader reader = new BinaryReader(ms))
                                    for (int i = 0; i <= bitmap.MipmapCount; i++)
                                    {
                                        byte[] data = reader.ReadBytes(bitmap_GetLength(bitmap.Format, mapWidth, mapHeight));
                                        if (data.Length > 0)
                                        {
                                            writer.Write(swizzled ? Swizzler.Swizzle(data, mapWidth, mapHeight, (int)depth, (int)file.RgbBitCount, swizzled) : data);
                                        }
                                        mapWidth /= 2; mapHeight /= 2;
                                    }

                    //Save
                    file.Save(string.Format(filename, b));
                }
            }
        }
コード例 #7
0
        /// <summary>
        /// This post process creates DirectX texture objects.
        /// </summary>
        public override void DoPostProcess()
        {
            // do the base post processing
            base.DoPostProcess();

            // init variables
            int count = bitmapValues.Bitmaps.Count;

            textures = new BaseTexture[count];
            ResourceType            type      = ParseType(bitmapValues.Type.Value);
            DirectDrawSurfaceHeader ddsHeader = new DirectDrawSurfaceHeader();

            // create size array
            int position = 0;

            int[] sizes = new int[count];
            for (int i = 0; i < count - 1; i++)
            {
                sizes[i]  = bitmapValues.Bitmaps[i + 1].PixelsOffset.Value - position;
                position += sizes[i];
            }
            sizes[count - 1] = bitmapValues.ProcessedPixelData.Binary.Length - position;

            // create textures
            for (int i = 0; i < count; i++)
            {
                short displayMipCount = bitmapValues.Bitmaps[i].MipmapCount.Value;
                if (type == ResourceType.Textures)
                {
                    displayMipCount = (short)Math.Max(1, displayMipCount - 2); // HACK: this prevents blackness taking over when we retreat from textures
                }
                Format       format       = ParseFormat(bitmapValues.Bitmaps[i].Format.Value);
                BinaryWriter memWriter    = ddsHeader.CreateMemoryStream(format == Format.P8 ? Format.A8R8G8B8 : format, bitmapValues.Bitmaps[i].Width.Value, bitmapValues.Bitmaps[i].Height.Value, bitmapValues.Bitmaps[i].Depth.Value, displayMipCount, type == ResourceType.CubeTexture);
                int          bitsPerPixel = format == Format.P8 ? 8 : ddsHeader.BitCount;
                byte[]       raw          = new byte[sizes[i]];

                Array.Copy(bitmapValues.ProcessedPixelData.Binary, bitmapValues.Bitmaps[i].PixelsOffset.Value, raw, 0, sizes[i]);
                if (type == ResourceType.CubeTexture)
                {
                    raw = ReorderCubeTexture(raw, bitmapValues.Bitmaps[i].Width.Value, bitmapValues.Bitmaps[i].Height.Value, bitmapValues.Bitmaps[i].MipmapCount.Value, bitsPerPixel);
                }

                if ((bitmapValues.Bitmaps[i].Flags.Value & SwizzledBit) != 0)
                {
                    raw = Swizzler.Swizzle(raw, bitmapValues.Bitmaps[i].Width.Value, bitmapValues.Bitmaps[i].Height.Value, bitmapValues.Bitmaps[i].Depth.Value, bitsPerPixel, /* i seem to remember this being right */ (bitmapValues.Bitmaps[i].Flags.Value & PalettizedBit) != 0);
                }

                if ((bitmapValues.Bitmaps[i].Flags.Value & PalettizedBit) != 0)
                {
                    raw = DePalettize(raw, ref bitsPerPixel);
                }

                memWriter.Write(raw);
                memWriter.Write(new byte[Compression.Pad(sizes[i], 0x80)]);
                memWriter.BaseStream.Position = 0;
                if (type == ResourceType.Textures)
                {
                    textures[i] = TextureLoader.FromStream(MdxRender.Device, memWriter.BaseStream);
                }
                else if (type == ResourceType.CubeTexture)
                {
                    textures[i] = TextureLoader.FromCubeStream(MdxRender.Device, memWriter.BaseStream);
                }
                else if (type == ResourceType.VolumeTexture)
                {
                    textures[i] = TextureLoader.FromVolumeStream(MdxRender.Device, memWriter.BaseStream);
                }
                else
                {
                    throw new HaloException("Unsupported texture type: {0}.", type);
                }
                // DEBUG:
                //TextureLoader.Save(System.Windows.Forms.Application.StartupPath + "\\texture dump\\" + Path.GetFileNameWithoutExtension(Name) + '[' + i.ToString() + "].dds", ImageFileFormat.Dds, textures[i]);
            }
        }
コード例 #8
0
        public static byte[] DecodeToDDS(GNFTexture texture)
        {
            var imageFormat     = ImageEngineFormat.DDS_DXT5;
            var dx10ImageFormat = DDS_Header.DXGI_FORMAT.DXGI_FORMAT_UNKNOWN;

            switch (texture.SurfaceFormat)
            {
            case GNF.SurfaceFormat.BC1:
                imageFormat = ImageEngineFormat.DDS_DXT1;
                break;

            case GNF.SurfaceFormat.BC2:
                imageFormat = ImageEngineFormat.DDS_DXT2;
                break;

            case GNF.SurfaceFormat.BC3:
                imageFormat = ImageEngineFormat.DDS_DXT5;
                break;

            case GNF.SurfaceFormat.BC4:
                imageFormat = ImageEngineFormat.DDS_ATI1;
                break;

            case GNF.SurfaceFormat.BC5:
                imageFormat = ImageEngineFormat.DDS_ATI2_3Dc;
                break;

            case GNF.SurfaceFormat.BC6:
                imageFormat     = ImageEngineFormat.DDS_DX10;
                dx10ImageFormat = DDS_Header.DXGI_FORMAT.DXGI_FORMAT_BC6H_UF16;
                break;

            case GNF.SurfaceFormat.BC7:
                imageFormat = ImageEngineFormat.DDS_DX10;

                switch (texture.ChannelType)
                {
                case ChannelType.Srgb:
                    dx10ImageFormat = DDS_Header.DXGI_FORMAT.DXGI_FORMAT_BC7_UNORM_SRGB;
                    break;

                default:
                    dx10ImageFormat = DDS_Header.DXGI_FORMAT.DXGI_FORMAT_BC7_UNORM;
                    break;
                }
                break;
            }

            var ddsHeaderSize = 0x80;

            if (dx10ImageFormat != DDS_Header.DXGI_FORMAT.DXGI_FORMAT_UNKNOWN)
            {
                ddsHeaderSize += 20;
            }

            var ddsBytes = new byte[ddsHeaderSize + texture.Data.Length];

            // create & write header
            var ddsHeader = new DDS_Header(1, texture.Height, texture.Width, imageFormat, dx10ImageFormat);

            ddsHeader.WriteToArray(ddsBytes, 0);

            // unswizzle
            var data = Swizzler.UnSwizzle(texture.Data, texture.Width, texture.Height, imageFormat == ImageEngineFormat.DDS_DXT1 ? 8 : 16, SwizzleType.PS4);

            // write pixel data
            Array.Copy(data, 0, ddsBytes, ddsHeaderSize, texture.Data.Length);

            return(ddsBytes);
        }