Пример #1
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);
        }
Пример #2
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);
        }